基礎知識和小技巧:
- 為了方便書寫,可以在記事本里寫存儲過程,寫完了貼到mysql里。
- delimiter命令用來指定mysql的命令結束符(默認是分號)。因為存儲過程是一段(若干行)mysql代碼,為了避免在錄入的時候就被執行了,需要用這個命令在寫存儲過程之前,把結束符改掉,寫完之后再改回來。所以常見的創建存儲過程代碼片段都以delimiter開頭和結尾。
- 為了方便調試(反復錄入),可以在存儲過程開始之前,先刪除可能存在錯誤存儲過程。命令:drop procedure if exists 存儲過程名
- 創建存儲過程,通常以create procedure 存儲過程名(參數)開頭,緊跟begin,end結尾。中間是編寫者發揮的地方。
簡單例子數據庫:
數據庫d1,表t1,t2。數字都是tinyint,字符串都是varchar(5)。
最簡單的存儲過程(不熟悉的時候,敲到記事本里,方便后面修改。之后不再提):
1 delimiter ~ 2 drop procedure if exists get_one~ 3 create procedure get_one() 4 begin 5 select xm from t1 limit 1; 6 end~ 7 delimiter ;
簡析:
7行,其實是4條命令。第1行,把結束符從分號換成~;第2行,如果存在則刪除;第3-6行是一條命令,創建存儲過程;第7行改回分號結束符。
重點在第3行,“create procedure”是創建存儲過程的命令,get_one是存儲過程的名稱,括號里是參數(沒有就不寫,但括號必須有)。
第4、6行是格式,也就是開始結束的標記。
運行:
call 存儲過程名。
關於存儲過程參數:
存儲過程的參數,用“變量名 類型"的方式寫在參數括號里。多個參數用逗號隔開。
在調用存儲過程的時候,由call命令傳入,在存儲過程的代碼里使用。
1 delimiter ~ 2 drop procedure if exists get_one~ 3 create procedure get_one(axh int) 4 begin 5 select * from t2 where xh=axh; 6 end~ 7 delimiter ;
運行結果:
關於變量和更多參數內容:
在存儲過程中可以使用以前學過的用戶變量。這些變量出了存儲過程仍然有效。
在存儲過程中還可以使用”declare 變量名 變量類型“來聲明變量(不帶@,注意不要和列名相同),這些變量必須放在begin后的第1行,且僅在存儲過程內有效。
如果希望存儲過程的參數能帶出來值,還可以在它前面加”in/out/inout“("in"可以省略,"out"表示只出不進,"inout"可進可出)。
例:
1 delimiter ~ 2 drop procedure if exists get_one~ 3 create procedure get_one(inout axh int,akm varchar(5)) 4 begin 5 declare b varchar(5); 6 set b=akm; 7 select * from t2 where xh=axh and km=b; 8 set axh=100; 9 end~ 10 delimiter ;
結果:
簡析:
第3行有兩個參數,所以調用的時候也用兩個參數,對應位置傳遞值。
第一個參數可進可出,所以第8行設置axh為100之后,結果圖片里的”@a“的值也就變成了100。
第5行聲明變量b,在第6行中就正常使用。這種變量不需要加”@“,出了存儲過程也就自動銷毀。
存儲過程結果的保存:
普通的查詢標量結果,可以用select into保存到變量中。其中用戶變量可以在存儲過程外面使用。
delimiter ~ drop procedure if exists get_one~ create procedure get_one(axh int) begin select * into @a,@b,@c from t1 where xh=axh; select @a; select @b; select @c; end~ delimiter ;
運行結果:
查詢結果是行、列、表的,可以考慮放在臨時表中。
臨時表是僅對當前連接有效的表。下面例子里涉及到的用法和含義,不清楚的可參考P21中下和P24中下。
1 delimiter ~ 2 drop procedure if exists get_one~ 3 create procedure get_one(axh int) 4 begin 5 drop temporary table if exists tmp_t1; 6 create temporary table tmp_t1 as select * from t2 where xh=axh; 7 select km,cj from tmp_t1; 8 end~ 9 delimiter ;
運行結果:
如果要查詢當前數據庫里有哪些存儲過程(root創建的),可以使用命令:
show PROCEDURE status where definer='root@localhost';
結果: