?簡單了解什么是存儲(chǔ)過程,以及存儲(chǔ)過程的使用場景毕源,和存儲(chǔ)函數(shù)浪漠、觸發(fā)氣的區(qū)別:
存儲(chǔ)過程,存儲(chǔ)函數(shù)霎褐,觸發(fā)器和事件是自從MySQL 5.0版本以來址愿,這些功能被添加到MySQL數(shù)據(jù)庫引擎,使mysql更加靈活和強(qiáng)大瘩欺。
存儲(chǔ)過程:
存儲(chǔ)過程(Stored Procedure)是一組為了完成特定功能的SQL語句集必盖,經(jīng)編譯后存儲(chǔ)在數(shù)據(jù)庫中,用戶通過指定存儲(chǔ)過程的名字并給定參數(shù)(如果該存儲(chǔ)過程帶有參數(shù))來調(diào)用執(zhí)行它俱饿。存儲(chǔ)過程是可編程的函數(shù)歌粥,在數(shù)據(jù)庫中創(chuàng)建并保存,可以由SQL語句和控制結(jié)構(gòu)組成拍埠。
存儲(chǔ)過程說白了就是一堆 SQL 的合并失驶。中間加了點(diǎn)邏輯控制。
使用場景:
存儲(chǔ)過程處理比較復(fù)雜的業(yè)務(wù)時(shí)比較實(shí)用枣购。比如說嬉探,一個(gè)復(fù)雜的數(shù)據(jù)操作擦耀。如果你在前臺(tái)處理的話∩蹋可能會(huì)涉及到多次數(shù)據(jù)庫連接眷蜓。但如果你用存儲(chǔ)過程的話。就只有一次胎围。從響應(yīng)時(shí)間上來說有優(yōu)勢吁系。也就是說存儲(chǔ)過程可以給我們帶來運(yùn)行效率提高的好處。另外白魂,程序容易出現(xiàn) BUG 不穩(wěn)定汽纤,而存儲(chǔ)過程,只要數(shù)據(jù)庫不出現(xiàn)問題福荸,基本上是不會(huì)出現(xiàn)什么問題的蕴坪。也就是說從安全上講,使用了存儲(chǔ)過程的系統(tǒng)更加穩(wěn)定敬锐。
其威力和優(yōu)勢主要體現(xiàn)在:?
?1.存儲(chǔ)過程只在創(chuàng)造時(shí)進(jìn)行編譯背传,以后每次執(zhí)行存儲(chǔ)過程都不需再重新編譯,而一般 SQL 語句每執(zhí)行一次就編譯一次,所以使用存儲(chǔ)過程可提高數(shù)據(jù)庫執(zhí)行速度滞造。
? 2.當(dāng)對(duì)數(shù)據(jù)庫進(jìn)行復(fù)雜操作時(shí)(如對(duì)多個(gè)表進(jìn)行Update,Insert,Query,Delete 時(shí))续室,可將此復(fù)雜操作用存儲(chǔ)過程封裝起來與數(shù)據(jù)庫提供的事務(wù)處理結(jié)合一起使用。這些操作谒养,如果用程序來完成挺狰,就變成了一條條的 SQL 語句,可能要多次連接數(shù)據(jù)庫买窟。而換成存儲(chǔ)過程丰泊,只需要連接一次數(shù)據(jù)庫就可以了。
? 3.存儲(chǔ)過程可以重復(fù)使用, 而且數(shù)據(jù)庫專業(yè)人員可以隨時(shí)對(duì)存儲(chǔ)過程進(jìn)行修改始绍,對(duì)應(yīng)用程序源代碼毫無影響,可減少數(shù)據(jù)庫開發(fā)人員的工作量瞳购。
? 4.安全性高,可設(shè)定只有某此用戶才具有對(duì)指定存儲(chǔ)過程的使用權(quán)。
存儲(chǔ)過程(procedure)和存儲(chǔ)函數(shù)(function)的區(qū)別:
1: 存儲(chǔ)函數(shù)和存儲(chǔ)過程統(tǒng)稱為存儲(chǔ)例程(store routine),存儲(chǔ)函數(shù)的限制比較多,例如不能用臨時(shí)表,只能用表變量,而存儲(chǔ)過程的限制較少,存儲(chǔ)過程的實(shí)現(xiàn)功能要復(fù)雜些,而函數(shù)的實(shí)現(xiàn)功能針對(duì)性比較強(qiáng)亏推。
2:存儲(chǔ)過程一般都是獨(dú)立使用学赛,使用call 加存儲(chǔ)過程名調(diào)用。而存儲(chǔ)函數(shù)可以在SQL語句(select)中使用(比如在查詢是經(jīng)常使用的系統(tǒng)自定義的sum 吞杭、avg 盏浇、max函數(shù))。
3:返回值不同 芽狗,存儲(chǔ)函數(shù)要求必須有返回值绢掰,且僅返回一個(gè)結(jié)果值,而存儲(chǔ)過程可以沒有返回值還可以返回一個(gè)結(jié)果集(out,inout)
4:參數(shù)不同,存儲(chǔ)函數(shù)的參數(shù)類似于存儲(chǔ)過程的IN入?yún)⒌尉ⅲ鎯?chǔ)過程即可有入?yún)N,也可由出參OUT,和INOUT
(1): IN 數(shù)據(jù)只是從外部傳入內(nèi)部使用(值傳遞),可以是數(shù)值也可以是變量
(2): OUT只允許過程內(nèi)部使用(不用外部數(shù)據(jù)),給外部使用的(引用傳遞:外部的數(shù)據(jù)會(huì)被先清空才會(huì)進(jìn)入到內(nèi)部),只能是變量
(3): INOUT 外部可以在內(nèi)部使用,內(nèi)部修改的也可以給外部使用,典型的引用 傳遞,只能傳遞變量
存儲(chǔ)過程和觸發(fā)器的區(qū)別:
觸發(fā)器是一種特殊的存儲(chǔ)過程攻晒,存儲(chǔ)過程需要手動(dòng)調(diào)用,而觸發(fā)器是經(jīng)過事件觸發(fā)而執(zhí)行的班挖,觸發(fā)器是綁定一張表鲁捏,在表中創(chuàng)建保存,而存儲(chǔ)過程是在一個(gè)數(shù)據(jù)庫中創(chuàng)建并保存聪姿。
觸發(fā)器=存儲(chǔ)過程+事務(wù)+自定義約束
存儲(chǔ)過程的編寫:
基本語法:
1)
存儲(chǔ)過程的參數(shù)有 入?yún)?IN碴萧, 出參OUT? , INOUT
IN從外部傳參在內(nèi)部使用,調(diào)用時(shí)必須傳值
OUT就是相當(dāng)于返回值
INOUT把出參和入?yún)⒎诺揭粔K兒末购,在調(diào)用時(shí)傳值,值可以返回
2)
declare用來聲明變量,default 賦默認(rèn)值虎谢,set 賦值
3)創(chuàng)建存儲(chǔ)過程:
delimiter$
Create
procedure 存儲(chǔ)過程名( )
Begin
……………(末尾要有? 分號(hào);?? )
End$
delimiter
注:delimiter$和 delimiter // 差不多盟榴,看每個(gè)人的習(xí)慣,delimiter是分割符婴噩,mysql 默認(rèn)’
; ’是分隔符擎场,如果不提前聲明分割符,編譯器會(huì)把存儲(chǔ)過程當(dāng)成 sql 語句執(zhí)行几莽,會(huì)報(bào)錯(cuò),
所以要事先用delimiter關(guān)鍵字聲明迅办,在用完以后 還要把分割符還原(如果不還原可能出現(xiàn)我下面寫例子的那種情況,一直結(jié)束不了章蚣,需要$符號(hào)后才能成功執(zhí)行站欺,這個(gè)窗口就廢了)。
4)調(diào)用存儲(chǔ)過程
Call存儲(chǔ)過程名( )??
注意:如果存儲(chǔ)過程后面必須加( ),如果有參數(shù) 在擴(kuò)內(nèi)寫上 參數(shù)
5)刪除存儲(chǔ)過程
Drop
procedure 存儲(chǔ)過程名
注意:不能刪除一個(gè) 在其他 存儲(chǔ)過程使用了的 存儲(chǔ)過程
6)顯示所有數(shù)據(jù)庫所有存儲(chǔ)過程的 基本信息
Showprocedure status
7)
show create procedure 存儲(chǔ)過程名
顯示某一個(gè)mysql存儲(chǔ)過程的詳細(xì)信息
一些例子:
無參無返回值:
查看book表中的所有數(shù)據(jù)
DELIMITER $
create procedure pro_test01()
begin
select * from? book;
end $
delimiter
調(diào)用: pro_test01();
有參無返回值:
根據(jù)name 查詢?cè)敿?xì)信息
delimiter $
?create procedure pro_test02(IN namevarchar(255))
?begin
?select* from book where bname=name;
?end$
delimiter
調(diào)用及結(jié)果:
無參有返回值:
查看book中有多少條記錄
delimiter $
create procedure pro_test03(OUT? sum int)
begin
select count(*) into sum from book;
end $
delimiter
調(diào)用及結(jié)果:
沒有寫delimiter 還原 了纤垂,一直結(jié)束不了矾策,只能輸$符
有參有返回值:
求從1 加到 num的和
delimiter $
?create procedure pro_test04(IN num int,OUTresult int)
?begin
?declarei int default 1;??? #定義一個(gè)變量i,初始值為 1
?declare sum int default 0;? #定義一個(gè)變量sum ,初始值為? 0
?WHILEi < num DO
?SETsum = sum +i;
?SETi = i+1;
?ENDWHILE;
?SETresult=sum;
?end$;
delimiter
調(diào)用及結(jié)果(1-10的和)
參數(shù)是INOUT
傳年份返回年齡
delimiter $
create procedure pro_test05(INOUT age int)
begin
set age = 2018 - age;
end $
delimiter
調(diào)用及結(jié)果
在設(shè)置變量的值時(shí) 要用set .? @代表局部表量峭沦,@@代表全局變量
if else? 用法
delimiter $
create procedurepro_test09(IN num int,OUT sys varchar(255))
begin
if num=0 then
set sys='等于0';
elseif num>0 then
set sys='大于0';
elseif num<0 then
set sys='小于0';
end fi
end$
delimiter