MySQL資料庫儲存過程
儲存過程(Stored Procedure)是在大型資料庫系統中,一組為了完成特定功能的SQL 語句集,儲存在資料庫中,經過第一次編譯後再次呼叫不需要再次編譯,使用者通過指定儲存過程的名字並給出引數(如果該儲存過程帶有引數)來執行它。儲存過程是資料庫中的一個重要物件。
——百度百科
如圖所示,在普通模式下獲取資料,使用者需要輸入SQL命令與資料庫進行互動,而儲存過程是編寫好的SQL命令,儲存在資料庫中,使用者操作的時候只需要呼叫儲存過程,而不用重新輸入冗餘繁雜的SQL命令。因此
- 儲存過程有什麼優點?
1.儲存過程可以重複使用,大大減小開發人員的負擔;
2.對於網路上的伺服器,可以大大減小網路流量,因為只需要傳遞儲存過程的名稱即可;
3,可以防止對錶的直接訪問,只需要賦予使用者儲存過程的訪問許可權。
0 儲存過程相關命令彙總
操作 | SQL命令 |
---|---|
建立儲存過程 | CREATE PROCEDURE 儲存過程名(引數種類1 引數1 資料型別1,[...] BEGIN 具體的procedure(處理) END |
檢視資料庫中的儲存過程 | SHOW PROCEDURE STATUS\G |
檢視具體的儲存過程 | SHOW CREATE PROCEDURE 儲存過程名\G |
呼叫(執行)儲存過程 | CALL 儲存過程名(引數1,...); |
刪除儲存過程 | DROP PROCEDURE 儲存過程名 |
變數宣告 | DECLARE 變數名 資料型別; |
變數賦值 | SET 變數名= ; |
1 儲存過程
1.1 建立儲存過程 CREATE PROCEDURE
建立儲存過程的命令是:
>CREATE PROCEDURE 儲存過程名(引數種類1 引數1 資料型別1,[...])
BEGIN
具體的procedure(處理)
END
- 1)儲存過程中具體的處理類容放在
BEGIN和END 之間;- 2)儲存過程需要制定引數,包括種類(
IN,OUT,INOUT ,分別代表輸入引數,輸出引數和即是輸入也是輸出的引數),引數名和資料型別。【和函式不同,函式指定輸入引數即可】
eg:建立一個對錶customer的姓名(nam)進行模糊檢索,命名為sp_search_customer。
對於上圖建立PROCEDURE的幾點說明:
①>DELIMITER //
表示給變分隔符,預設分隔符是;
,否則儲存過程中含有;
,MySQL監視器無法分辨。(最後將分隔符改回來)
②儲存過程(
分類 | SQL命令 |
---|---|
簡單條件 | IF cond1 THEN exp1 ELSEIF cond2 THEN exp2 ELSE expelse END IF |
case | CASE 表示式 WHEN 值1 THEN … WHEN …THEN… ELSE … END CASE |
迴圈(後置判斷) | REPEAT … UNTIL …END REPEAT |
迴圈(前置判斷) | WHILE … DO … END WHILE |
**1.2 檢視儲存過程** 檢視資料庫中是否存在儲存過程:
>SHOW PROCEDURE STATUS\G
檢視儲存過程的具體資訊:
>SHOW CREATE PROCEDURE 儲存過程名\G
eg:檢視儲存過程sp_search_customer
1.3 執行儲存過程 CALL
呼叫儲存過程使用CALL 儲存過程名
命令,具體如下:
CALL 儲存過程名(引數,...)
eg:通過建立好的儲存過程sp_search_cusotmer來執行儲存過程:
檢索‘王’姓顧客:
>CALL sp_search_customer('王%');
檢索所有顧客:
>CALL sp_search_customer('');
1.4 刪除儲存過程 DROP PROCEDURE
刪除儲存過程使用命令:
DROP PROCEDURE 儲存過程名;
2 儲存過程優化
(1)使用if條件語句建立儲存過程
可以看到,上述條件語句部分的結構大致都為:
IF... THEN
SELECT...;
ELSEIF ...THEN
SELECT...;
ELSEIF...THEN
SELECT...;
ELSE
SELECT...;
其中的語句具有較高的重複性和冗餘性,因此比較繁瑣,如果我們用CASE替代呢?
(2)CASE命令的多重分支
使用CASE來建立多重分支:
p_dapart
放到CASE之後,一個p_dapart
取代了多個p_dapart
,因此使用CASE程式碼在判斷語句處顯得簡潔一些,如果通過定義變數的形式呢?
(3)定義本地變數
儲存過程中定義的變數,被稱為本地變數,對程式設計語言有所瞭解的知道這是一個區域性變數。資料庫中,
宣告區域性變數的命令:
>DECLARE 變數名 資料型別 [初始值...]
給變數賦值的命令:
>SET 變數名=
,在建立procedure過程中頂一個本地變數tem:
可以看到,這種方式大大地簡化了程式碼的冗餘性和重複性。
3 再說儲存過程的輸出引數
在建立儲存過程的時候,如果制定了
eg:建立一個計算階乘的儲存過程:
最終的結果將儲存到“@res“之中,如上圖所示。
- 請注意,用
WHILE 迴圈建立的計算階乘的儲存過程,!5=120,!0=1 ,結果是正確的。先記住這句話,接下來看下用REPEAT建立同樣的階乘計算的儲存過程。
4 再說WHILE 和 REPEAT迴圈
我們使用repeat建立一個計算階乘的儲存過程:
接下來看下同樣計算
可以看到!5=120的結果正確,但是!0得到的結果為0,不為1。這是什麼原因呢?
問題出在WHILE是前置判斷,是先驗的,先驗證WHILE後面的條件是否成立,為TRUE則繼續執行,若FALSE則結束迴圈;
而REPEAT是後置判斷,是後驗的,不管三七二十一先執行語句,然後驗證UNTIL後面的條件語句是否成立,不成立則結束。因此REPEAT迴圈執行了一次
因此:
- WHILE迴圈是前置判斷,先驗的迴圈
- REPEAT迴圈是後置判斷,後驗的迴圈