MySQL存储过程

时间:2017-06-07 11:53:28   收藏:0   阅读:423

 简介

  存储过程就是一条或多条SQL语句的集合,当对数据库进行一系列复杂操作时,存储过程可以将这些复杂的操作封装程一个代码块,可以重复使用,大大减少数据库开发人员的工作量。

 存储过程的创建

  创建存储过程

  使用CREATE PROCEDURE语句创建存储过程,基本语法格式如下:

CREATE PROCEDURE sp_name([proc_parameter])
[characteristics...]routine_body

  上述语法格式中CREATE PROCEDURE:为用来创建存储过程的关键字;sp_name:存储过程的名称;proc_parameter:存储过程的参数列表,该参数列表形式如下:

[IN|OUT|INOUT] param_name type

  上述参数列表形式中 IN:输入参数;OUT:输出参数;INOUT:即可以输入也可以输出;param_name:参数名称;type:参数类型,可以是MySQL数据库中的任意类型;

  在创建存储过程语法中,characteristics用于指定存储过程的特性,取值具体说明如下:

  routime_bodySQL代码的内容,可以用BEGIN…END来表示SQL代码的开始和结束

  创建存储过程案例

mysql> DELIMITER //
mysql> CREATE PROCEDURE Proc ()
    -> BEGIN
    -> SELECT * FROM table_name;
    -> END //
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;

  在上述执行过程中,“DELIMITER //”语句的作用是将MySQL的结束符设置为//,因为MySQL默认的语句结束符号为分号“;”,为了避免与存储过程中SQL语句结束符相冲突,需要使用DELIMITER改变存储过程的结束符,并以“END //”结束存储过程。存储过程定义完毕后再使用“DELIMITER ;”恢复默认结束符。DELIM-ITER也可以指定其他符号作为结束符。需要格外注意的是,DELIMITER与要设定的结束符之间一定要有一个空格,否则设定无效

  变量的使用

  在编写存储过程时,有时会需要使用变量保存数据处理过程中的值。在MySQL中,变量可以在子程序中声明并使用,这些变量的作用范围是在BEGIN…END程序中

DECLARE var_name[,varname]…date_type[DEFAULT value];

  上述语法格式中var_name:局部变量的名称;DEFAULT value子句给变量提供一个默认值。该值除了可以被声明为一个常数之外,还可以被指定为一个表达式。如果没有DEFAULT子句,变量的初始值为NULL。

  接下来定义一个名称为myvariable的变量,类型为INT类型,默认值为100,示例代码如下:

DECLARE myvariable INT DEFAULT 100;
SET var_name = expr[,var_name = expr]…;

  在存储过程中的SET语句是一般SET语句的扩展版本。被参考变量可能是子程序内声明的变量,或者是全局服务器变量,如系统变量或者用户变量。

  在存储程序中的SET语句作为预先存在的SET语法的一部分来实现。这允许SET a=x,b=y,…这样的扩展语法。其中不同的变量类型(局域声明变量及全局变量)可以被混合起来。这也允许把局部变量和一些只对系统变量有意义的选项合并起来。

  接下来声明三个变量,分别为var1、var2、var3,数据类型为INT,使用SET为变量赋值,示例代码如下:

DECLARE var1,var2,var3 INT;
SET var1=10,var2=20;
SET var3=var1+var2;
SET @x=var1+var2;

  注意:“@x”表示用户变量,使用SET语句为其赋值,用户变量与连接有关,一个客户端定义的变量不能被其他客户端看到或使用。当客户端退出时,该客户连接的所有变量将自动释放。

SELECT col_name[] INTO var_name[] table_expr;

  在上述语法格式中,col_name表示字段名称;var_name表示定义的变量名称;table_expr表示查询条件表达式,包括表名称和WHERE子句。

  :声明变量s_grade和s_gender,通过SELECT…INTO语句查询指定记录并为变量赋值,具体代码如下:

DECLARE s_grade FLOAT;
DECLARE s_gender CHAR(2);
SELECT grade, gender INTO s_grade, s_gender
FROM student WHERE name = rose;

  定义条件和处理程序

  定义条件是事先定义程序执行过程中遇到的问题,处理程序定义了在遇到这些问题时应当采取的处理方式,并且保证存储过程在遇到警告或错误时能继续执行。

  光标的使用

  在编写存储过程时,查询语句可能会返回多条记录,如果数据量非常大,则需要使用光标来逐条读取查询结果集中的记录。光标是一种用于轻松处理多行数据的机制。

  流程控制的使用 

  在编写存储过程时还有一个非常重要的部分——流程控制。MySQL中的流程控制语句包括:IF语句、CASE语句、LOOP语句、WHILE语句、LEAVE语句、ITERATE语句、REPEAT语句和WHILE语句。

  每个流程中可能包含一个单独语句,也可能是使用BEGIN…END构造的复合语句,可以嵌套。

 存储过程的使用

  调用存储过程

  存储过程必须用CALL语句调用,如果调用其他数据库的存储过程,需要指定数据库名。调用语法格式如下:

CALL sp_name([parameter[,…]])

  其中,sp_name:存储过程的名称;parameter:存储过程的参数;

  例:定义一个名为CountProc1的存储过程,然后调用这个存储过程,具体操作如下:

  1. 定义存储过程:
    mysql> DELIMITER //
    mysql> CREATE PROCEDURE CountProc1(IN s_gender VARCHAR(50),OUT num INT)
        -> BEGIN
        -> SELECT COUNT(*) INTO num FROM student WHERE gender= s_gender;
        -> END//
    Query OK, 0 rows affected (0.13 sec)
    mysql> DELIMITER;
  2. 调用存储过程:
    mysql> CALL CountProc1("女",@num);
    Query OK, 1 row affected (0.17 sec)
  3. 查看返回结果
    mysql> SELECT @num;
    +------+
    | @num |
    +------+
    |  2   |
    +------+
    1 row in set (0.00 sec)

  查看存储过程

  1. SHOW STATUS语句
    基本语法结构:
    SHOW {PROCEDURE|FUNCTION} STATUS [LIKE ‘pattern‘\]

    上述语法格式中,PROCEDURE和FUNCTION分别表示查看存储过程和函数,LIKE语句表示匹配的名称。

    示例:获取数据库中所有名称以C开头的存储过程的信息。
    SHOW PROCEDURE STATUS LIKEC%\G
  2. SHOW CREATE语句
    基本语法结构:
    SHOW CREATE{PROCEDURE|FUNCTION} sp_name

    示例:

    SHOW CREATE PROCEDURE chapter06.CountProc1\G
  3. 从information_schema.Routines表中查看存储过程的信息
    在MySQL中存储过程和函数的信息存储在information_schema数据库下的Routines表中。可以通过查询该表的记录来查询存储过程的信息,查询语句如下:
    SELECT * FROM  information_schema.RoutinesWHERE ROUTINE_NAME=CountProc1 AND ROUTINE_TYPE=PROCEDURE\G

    需要注意的是,ROUTINE_NAME:指定存储过程的名称;ROUTINE_TYPE:指定存储程序的类型。

  修改存储过程

  使用ALTER语句修改存储过程的特性,其基本语法格式如下:

ALTER {PROCEDURE|FUNCTION} sp_name[characteristic…]

  上述语法格式中,sp_name:存储过程或函数的名称;characteristic表示要修改存储过程的哪个部分,characteristic的取值具体如下:

  1. CONTAINS SQL表示子程序包含SQL语句,但不包含读或写数据的语句;
  2. NO SQL表示子程序中不包含SQL语句;
  3. READS SQL DATA表示子程序中包含读数据的语句;
  4. MODIFIES SQL DATA表示子程序中包含写数据的语句;
  5. SQL SECURITY{DEFINER|INVOKER}指明谁有权限来执行;(DEFINER:只有定义者自己才能够执行;INVOKER:调用者可以执行)
  6. COMMENT‘string’表示注释信息。

  目前,MySQL还不提供对已存在的存储过程代码的修改,如果一定要修改存储过程代码,必须先将存储过程删除之后,再重新编写代码,或创建一个新的存储过程。

  删除存储过程

  使用DROP语句删除存储过程,其基本语法格式如下:

DROP{ PROCEDURE|FUNCTION }[IF EXISTS] sp_name

  示例:删除存储过程CountProc1

DROP PROCEDURE CountProc1;

  综合案例-存储过程应用

  1. 创建一个stu表
    表结构:
    技术分享
    表数据:
    技术分享
    建表及初始化数据脚本:
    CREATE TABLE stu(id INT,name VARCHAR(50),class VARCHAR(50));
    INSERT INTO stu VALUE (1,Lucy,class1),(2,Tom,class1),(3,Rose,class2);
  2. 创建一个存储过程
    创建一个存储过程addcount能够获取表stu中的记录数和id的和,代码格式如下:
    CREATE PROCEDURE addcount(out count INT)
    BEGIN
    DECLARE itmp INT;
    DECLARE cur_id CURSOR FOR SELECT id FROM stu;
    DECLARE EXIT HANDLER FOR NOT FOUND CLOSE cur_id;
    SELECT count(*) INTO count FROM stu;
    SET @sum=0;
    OPEN cur_id;
    REPEAT
    FETCH cur_id INTO itmp;
    IF itmp<10
    THEN SET @sum=@sum+itmp;
    END IF;
    UNTIL 0 END REPEAT;
    CLOSE cur_id;
    END;

    上述存储过程用到了变量的声明、光标、流程控制。SQL语句执行情况如下:

    mysql> DELIMITER //
    mysql> CREATE PROCEDURE addcount(out count INT)
        -> BEGIN
        -> DECLARE itmp INT;
        -> DECLARE cur_id CURSOR FOR SELECT id FROM stu;
        -> DECLARE EXIT HANDLER FOR NOT FOUND CLOSE cur_id;
        -> SELECT count(*) INTO count FROM stu;
        -> SET @sum=0;
        -> OPEN cur_id;
        -> REPEAT
        -> FETCH cur_id INTO itmp;
        -> IF itmp<10
        -> THEN SET @sum=@sum+itmp;
        -> END IF;
        -> UNTIL 0 END REPEAT;
        -> CLOSE cur_id;
        -> END //
    Query OK, 0 rows affected (0.00 sec)
    mysql> CALL addcount(@count) //
    Query OK, 0 rows affected (0.00 sec)
    mysql> SELECT @count,@sum //
    +--------+------+
    | @count | @sum |
    +--------+------+
    |    3   |    6 |
    +--------+------+
    1 row in set (0.00 sec)
    mysql> DELIMITER;

    从调用存储过程的结果可以看出,stu表中共有三条数据,id之和为6。这个存储过程创建了一个cur_id的光标,使用这个光标来获取每条记录的id,使用REPEAT循环语句来实现所有id号相加。

原文:http://www.cnblogs.com/cb0327/p/6875300.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!