當前數據庫中有一張acount表,如下:
一、存儲過程的創建:
(1)語法:mysql> CREATE PROCEDURE 創建的存儲過程名字(OUT|IN|INOUT 參數名 數據類型,...,...) 特徵 過程體;
解析如下圖:
(2)使用:
列出存儲過程的詳細列表:show procedure status;
刪除:drop procedure 要刪除的存儲過程的名字;
查看創建存儲過程的信息:show create procedure 創建的存儲過程名字;
查看所有存儲過程:show procedure status \G;
(3)示例:
創建一個存儲過程pshow,不帶參數:
調用該存儲過程pshow();注意調用的時候不帶參數的不用加括號
創建一個帶參數的存儲過程pfun:
調用存儲過程pfun
call procedure();//無參
call procedure(@x,@y,****);//有參數(此處x、y爲輸出參數,****爲輸入參數)
用完後,直接使用select @x,@y;來查詢x、y的值。
查看目前所有的存儲過程
二、存儲函數:
(1)語法:CREATE FUNCTION 創建的存儲函數名字(參數名稱 參數類型,...,...) RETURNS 返回值得類型 函數體;
(2)使用
調用存儲函數:select 函數名字([參數]);//根據定義函數的形參,形參與實參保持一致
查看創建函數信息:show create function 函數名字 /G;
查看所有自定義函數:show function status \G;
刪除存儲函數:drop function 函數名字;
(3)示例:
創建一個存儲函數fnameshow:
調用存儲函數:
創建一個帶參數的存儲函數mydelete
調用:
再查看錶,發現id=5的這一行被刪除了:
查看存儲函數:
三、觸發器:
(1)、語法:
CREATE TRIGGER 創建的觸發器名字 BEFFOR|AFTER INSERT|UPDATE|DELETE
ON 表名字 FOR 觸發器的執行間隔 觸發器的SQL語句
解析如下表:
注意(摘自網絡):
觸發程序與要創建觸發器的表相關。該表必須引用永久性表。不能將觸發程序與臨時表表或視圖關聯起來。
觸發程序的動作時間BEFORE或AFTER,以指明觸發程序是在激活它的語句之前或之後觸發。
激活觸發程序的語句的類型。下述值之一:
· INSERT:將新行插入表時激活觸發程序,例如,通過INSERT、LOAD DATA和REPLACE語句。
· UPDATE:更改某一行時激活觸發程序,例如,通過UPDATE語句。
· DELETE:從表中刪除某一行時激活觸發程序,例如,通過DELETE和REPLACE語句。
請注意,trigger_event與以表操作方式激活觸發程序的SQL語句並不很類似,這點很重要。
例如,關於INSERT的BEFORE觸發程序不僅能被INSERT語句激活,也能被LOAD DATA語句激活
(2)使用
查看所有的觸發器:show triggers \G;
刪除觸發器:drop trigger 觸發器名字;
(3)示例
創建一個插入型觸發器
更新表中的數據,查看錶,發現id=4的balance由原來的500變爲了509
查看觸發器
四、存儲過程、存儲函數和觸發器的對比:
(1)基本區別:
(2)優缺點對比:
存儲過程:
優點:
*有if/else,case,while等控制語句,通過編寫存儲過程,可以實現一些邏輯比較複雜的功能;
*模塊化;對一些功能進行了封裝,代碼的複用;
*響應速度快,只有在首次執行時需要經過編譯和優化步驟,後被調用直接執行,省去了重新編寫代碼計算的步驟。
*減少網絡傳輸。存儲過程直接就在數據庫服務器上跑,所有的數據訪問都在服務器內部進行,不需要傳輸數據到其它終端。
*方便DBA優化。所有的SQL集中在一個地方
缺點:
*複雜的業務邏輯。沒辦法應用緩存。
觸發器
優點:
*安全。可以基於數據庫的值使用戶具有操作數據庫的某種權利。可以跟蹤用戶對數據庫的操作。
*觸發器能夠拒絕或回退那些破壞相關完整性的變化,取消試圖進行數據更新的事務。當插入一個與其主健不匹配的外部鍵時,這種觸發器會起作用。
缺點:
*數據集數據量又較大時,觸發器效果會非常低(因爲自動計算數據值,需要變動整個數據集導致效率下降)
*對於批量操作並不適合使用觸發器,使用觸發器實現的業務邏輯在出現問題時很難進行定位。
五、注意事項:
在MySQL中,默認以分號爲分隔符,在寫存儲過程、存儲函數、觸發器時,編譯器會當做SQL語句來進行處理,編譯過程會出現錯誤,所以要事先用”delimiter @”聲明@(或者其他,由用戶自己定義)爲當前的段分隔符,讓編譯器把兩個@之間的內容當做存儲過程、存儲函數、觸發器的代碼,在寫完整個內容完之後再”delimiter ;”將分隔符還原。