1、基本語法及簡單實例html
一、建立簡單的測試環境java
mysql> use test; Database changed mysql> show tables; Empty set (0.00 sec) mysql> CREATE TABLE t(s1 INT); Query OK, 0 rows affected (0.06 sec) mysql> INSERT INTO t VALUES(5); Query OK, 1 row affected (0.02 sec)
二、選擇分隔符mysql
mysql> DELIMITER //
咱們通常使用";"做爲分隔符,可是在編寫存儲過程的時候這會帶來一些問題,由於存儲過程當中有許多語句,修改會";"做爲分隔符可以使用語句"DELIMITER ;//"。sql
三、建立存儲過程數據庫
mysql> CREATE PROCEDURE p1() SELECT * FROM t;// Query OK, 0 rows affected (0.08 sec)
"CREATE PROCEDURE"即爲SQL語句部分,第二部分是過程名"p1"(這裏須要注意的是存儲過程名對大小寫不敏感)。express
第三部分 () 是參數列表,一般須要在其中添加參數,這裏參數爲空,可是"()"必須存在。oop
"SELECT * FROM t;"是存儲過程的主體,注意哦,";"是主體的一部分哦,建立該存儲過程的語句的真正結束符爲"//"。學習
另外須要注意的一點是,和咱們建立表同樣,在建立存儲過程前面須要檢查是否存在同名的存儲過程,即" DROP PROCEDURE IF EXISTS p1;",沒錯這正是刪除一個存儲過程的SQL語句。另外,不能在一個存儲過程當中刪除另外一個存儲過程,只能調用另外一個存儲過程。測試
四、調用存儲過程spa
mysql> CALL p1()// +------+ | s1 | +------+ | 5 | +------+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec)
這裏只是簡單的調用,在下一點關於參數的使用辦法中有更爲複雜的調用。
五、參數(Parameter)
mysql> CREATE PROCEDURE p2(p INT) SET @x = p ;// Query OK, 0 rows affected (0.02 sec) mysql> CALL p2(123)// Query OK, 0 rows affected (0.00 sec) mysql> SELECT @x// +------+ | @x | +------+ | 123 | +------+ 1 row in set (0.01 sec)
這是輸入參數的例子,咱們選擇了會話變量@x證實成功的將參數傳入了改變量。
mysql> CREATE PROCEDURE p3(OUT p INT) -> SET p = -5;// Query OK, 0 rows affected (0.00 sec) mysql> CALL p3(@y)// Query OK, 0 rows affected (0.01 sec) mysql> SELECT @y// +------+ | @y | +------+ | -5 | +------+ 1 row in set (0.00 sec)
這是輸出參數的例子,咱們選擇會話變量@y去接收存儲過程p3輸出參數的值。
六、變量(Variables)
CREATE PROCEDURE P5() BEGIN DECLARE a INT; DECLARE b INT; SET a = 5; SET b = 5; INSERT INTO t VALUES(a); SELECT s1 FROM t WHERE s1>= b; END; ------------------------------------------------- mysql> CALL p5(); +----+ | s1 | +----+ | 5 | | 5 | +----+ 2 rows in set Query OK, 0 rows affected
在過程當中定義的變量並非真正的定義,你只是在BEGIN/END(即複合語句)塊內定義了而已。注意這些變量和會話變量不同,不能使用修飾符@你必須清楚的在BEGIN/END塊中聲明變量和它們的類型。變量一旦聲明,你就能在任何能使用會話變量、文字、列名的地方使用。還須要注意的一點是,在一個塊內,咱們須要把全部要使用的變量先聲明,才能在後面使用,而且不能在聲明變量的語句間夾雜其餘使用變量的語句,否會報語法錯誤。
CREATE PROCEDURE P6() BEGIN DECLARE a,b INT DEFAULT 5; INSERT INTO t VALUES(a); SELECT s1 * a FROM t WHERE s1>= b; END; ------------------------------------------------------ mysql> CALL p6(); +--------+ | s1 * a | +--------+ | 25 | | 25 | | 25 | +--------+
這裏使用DEFAULT子句來設定初始值,如此咱們能夠不須要把DECLARE和SET語句的實現分開。
七、區塊的定義使用
通常形式爲
begin ...... end;
也能夠給區塊起別名,如:
lable:begin ........... end lable;
能夠用leave lable;跳出區塊,執行區塊之後的代碼。
八、條件語句
通常形式爲
if 條件 then statement else statement end if;
實例:
CREATE PROCEDURE p7(IN param1 INT) BEGIN DECLARE v1 INT; SET v1 = param1 + 1; IF v1 = 0 THEN INSERT INTO t VALUES(17); END IF; IF param1 = 0 THEN UPDATE t SET s1 = s1 + 1; ELSE UPDATE t SET s1 = s1 + 2; END IF; END;// ----------------------------------------------------------- mysql> SELECT * FROM t; +----+ | s1 | +----+ | 6 | | 6 | | 6 | +----+ 3 rows in set mysql> CALL p7(0); Query OK, 3 rows affected mysql> CALL p7(0); Query OK, 3 rows affected mysql> SELECT * FROM t; +----+ | s1 | +----+ | 8 | | 8 | | 8 | +----+ 3 rows in set
過程很簡單,能夠看出調用兩次即執行了兩次UPDATE t SET s1= s1 + 1;語句。另外還有CASE指令,使用辦法和IF同樣簡單,簡單實例以下:
CREATE PROCEDURE p8(IN param1 INT) BEGIN DECLARE v1 INT; SET v1 = param1 + 1; CASE v1 WHEN 0 THEN INSERT INTO tVALUES(17); WHEN 1 THEN INSERT INTO tVALUES(18); ELSE INSERT INTO tVALUES(19); END CASE; END;//
九、循環語句
1)while循環
[label:] WHILE expression DO statements END WHILE [label] ;
實例:
CREATE PROCEDURE p9 () BEGIN DECLARE v INT; SET v = 0; WHILE v < 5 DO INSERT INTO t VALUES(v); SET v = v + 1; END WHILE; END; //
2)repeat until循環
[label:] REPEAT statements UNTIL expression END REPEAT [label] ;
實例:
CREATE PROCEDURE p10 () BEGIN DECLARE v INT; SET v = 0; REPEAT INSERT INTO t VALUES(v); SET v = v + 1; UNTIL v >= 5 END REPEAT; END; //
3)loop循環
[label:] LOOP statements END LOOP[label];
實例:
CREATE PROCEDUREp11 () BEGIN DECLARE v INT; SET v = 0; loop_label: LOOP INSERT INTO t VALUES (v); SET v = v + 1; IF v >= 5 THEN LEAVE loop_label; END IF; END LOOP; END; //
十、其餘經常使用命令
1)showprocedure status
顯示數據庫中全部存儲的存儲過程基本信息,包括所屬數據庫,存儲過程名稱,建立時間等
2)show createprocedure sp_name
顯示某一個存儲過程的詳細信息
2、常見錯誤及處理辦法
一、[Err] 1064 -You have an error in your SQL syntax; check the manual that corresponds to yourMySQL server version for the right syntax to use near '***'
很簡單,1064即爲SQL語法錯誤,仔細檢查錯誤提示信息所指語句附近改正便可。
例:
CREATE PROCEDURE P12() BEGIN DECLARE a INT; SET a = 5; DECLARE b INT; SET b = 5; INSERT INTO t VALUES(a); SELECT s1 FROM t WHERE s1>= b; END;
提示信息爲:
[Err] 1064 - You have an error in your SQL syntax; check the manualthat corresponds to your MySQL server version for the right syntax to use near'DECLARE b INT;
SET b = 5;
INSERT INTO t VALUES(a);
SELECT s1 FROM t WHE' at line 5
提示在第5行,咱們發如今變量聲明語句"DECLARE b INT;"的前面有一條賦值語句"SET a = 5;",只需將其放到全部變量聲明語句以後便可。
二、[Err] 1318 -Incorrect number of arguments for PROCEDURE *.*; expected *, got *
如提示信息,database_name.procedure_name的存儲過程傳入的參數個數不對。
例:
CREATE PROCEDURE p13(OUT p INT) SET p = -5; CALL p13();
提示信息爲:
[Err] 1318 - Incorrect number of arguments for PROCEDURE test.p13;expected 1, got 0
改成CALL p13(@a); 便可。
三、[Err] 1414 -OUT or INOUT argument 1 for routine *.* is not a variable or NEWpseudo-variable in BEFORE trigger
此信息也是提示咱們傳入的參數不對,*.*的存儲過程參數爲輸出(或輸入)參數,而咱們可能傳入相反的參數,例如要求爲輸出參數,而咱們傳入的參數非會話變量,即會報此錯。
例:
CALL p13(a); -- 或者CALL p13(0);
提示信息:
[Err] 1414 - OUT or INOUT argument 1 for routine test.p13 is not avariable or NEW pseudo-variable in BEFORE trigger
改正:
CALL p13(@a);
SELECT @a;
參考資料:
一、《mysql 5.0存儲過程學習總結》--平凡的世界http://www.ccvita.com/100.html
二、《MYSQL 5.0存儲過程》--Peter Gulutzan 著 陳朋奕 譯