存儲過程
原文來自https://segmentfault.com/a/1190000006756268
存儲過程簡單來說,就是為以后的使用而保存的一條或多條MySQL語句的集合魄宏【槁睿可將其視為批件台盯,雖然它們的作用不僅限于批處理。
在我看來畏线, 存儲過程就是有業(yè)務(wù)邏輯和流程的集合静盅, 可以在存儲過程中創(chuàng)建表,更新數(shù)據(jù)寝殴, 刪除等等蒿叠。
為什么要使用存儲過程
- 通過把處理封裝在容易使用的單元中,簡化復(fù)雜的操作(正如前面例子所述)蚣常。
- 由于不要求反復(fù)建立一系列處理步驟市咽,這保證了數(shù)據(jù)的完整性。如果所有開發(fā)人員和應(yīng)用程序都使用同一(試驗和測試)存儲過程抵蚊,則所使用的代碼都是相同的施绎。這一點的延伸就是防止錯誤溯革。需要執(zhí)行的步驟越多,出錯的可能性就越大谷醉。防止錯誤保證了數(shù)據(jù)的一致性致稀。
- 簡化對變動的管理。如果表名俱尼、列名或業(yè)務(wù)邏輯(或別的內(nèi)容)有變化抖单,只需要更改存儲過程的代碼。使用它的人員甚至不需要知道這些變化遇八。
一個簡單的存儲過程
create procedure porcedureName ()
begin
select name from user;
end;
存儲過程用create procedure 創(chuàng)建矛绘, 業(yè)務(wù)邏輯和sql寫在begin和end之間。mysql中可用call porcedureName ();來調(diào)用過程刃永。
-- 調(diào)用過程
call porcedureName ();
該存儲過程沒有參數(shù)货矮, 只是在調(diào)用的時候查詢了用戶表的用戶名而已, 調(diào)用結(jié)果如下
name |
---|
admin |
admin1 |
admin2 |
admin3 |
刪除存儲過程
DROP PROCEDURE IF EXISTS porcedureName; -- 沒有括號()
使用參數(shù)的存儲過程
create procedure procedureName(
out min decimal(8,2),
out avg decimal(8,2),
out max decimal(8,2)
)
BEGIN
select MIN(price) INTO min from order;
select AVG(price) into avg from order;
select MAX(price) into max from order;
END;
此過程接受三個參數(shù)揽碘, 分別用于獲取訂單表的最小次屠、平均、最大價格雳刺。每個參數(shù)必須具有指定的類
型,這里使用十進(jìn)制值(decimal(8,2))裸违, 關(guān)鍵字OUT指出相應(yīng)的參數(shù)用來從存儲過程傳出
一個值(返回給調(diào)用者)
MySQL支持IN(傳遞給存儲過程)掖桦、OUT(從存儲過程傳出,如這里所用)和INOUT(對存儲過程傳入和傳出)類型的參數(shù)供汛。存儲過程的代碼位于BEGIN和END語句內(nèi)枪汪,如前所見,它們是一系列SELECT語句怔昨,用來檢索值雀久,然后保存到相應(yīng)的變量(通過指定INTO關(guān)鍵字)
為調(diào)用此修改過的存儲過程,必須指定3個變量名趁舀,如下所示:(所有MySQL變量都必須以@開始赖捌。)
-- 由于過程指定三個參數(shù), 故調(diào)用必須要參數(shù)匹配
call procedureName(@min, @avg, @max);
該調(diào)用并沒有任何輸出矮烹, 只是把調(diào)用的結(jié)果賦給了調(diào)用時傳入的變量(@min, @avg, @max)越庇。然后即可調(diào)用顯示該變量的值。
select @min, @avg, @max;
@min | @avg | @max |
---|---|---|
42.00 | 601.00 | 2222.00 |
結(jié)果如下
@min | @avg | @max |
---|---|---|
42.00 | 601.00 | 2222.00 |
使用in參數(shù), 輸入一個用戶id奉狈, 返回該用戶所有訂單的總價格卤唉。
create procedure getTotalById (
in userId int,
out total decimal(8,2)
)
BEGIN
select SUM(r.price) from order r
where r.u_id = userId
into total;
END;
調(diào)用存儲過程
call getTotalById(1, @total);
select @total;
結(jié)果將返回該用戶所有訂單的合計價格。
復(fù)雜一點的過程仁期, 根據(jù)用戶id獲取該用戶的所有訂單價格桑驱, 并動態(tài)的選擇是否加稅竭恬。代碼設(shè)計如下
create procedure getTotalByUser2(
in userId int,
in falg boolean, -- 是否加稅標(biāo)記
out total decimal(8,2)
)
begin
DECLARE tmptotal DECIMAL(8,2);
DECLARE taxrate int DEFAULT 6;-- 默認(rèn)的加稅的利率
select SUM(r.price) from order r
where r.u_id = userId
into tmptotal;
if taxable then
select tmptotal + (tmptotal/1000*taxrate) into tmptotal;
end if;
select tmptotal into total;
END;
該過程傳入三個參數(shù), 用戶id熬的, 是否加稅以及返回的總價格痊硕,在過程內(nèi)部, 定義兩個局部變量tmptotal和taxrate悦析,把查詢出來的結(jié)果賦給臨時變量寿桨, 在判斷是否加稅。最后把局部變量的值賦給輸出參數(shù)强戴。
call getTotalByUser2(1, false, @total); -- 不加稅
call getTotalByUser2(1, true, @total); -- 加稅
select @total;
參考自mysql必知必會亭螟, 轉(zhuǎn)載請注明出處。