MySQL存储过程学习笔记

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 著 陈朋奕 译

相关文章
相关标签/搜索