MySQL学习笔记之MySQL存储过程

一、存储过程简介

  SQL语句需要先编译再执行,而存储过程(stored procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名称并给定参数(若该存储过程带有参数)来调用执行。
  一个存储过程是一个可编程的函数,在数据库中创建并保存,可以SQL语句和一些特殊控制结构组成。当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能,存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟,允许控制数据的访问方式。
  存储过程通常有一下优点:
        1)增强SQL语言的功能和灵活性。存储过程可以用流程控制语句编写,有很强的的灵活性,可以完成复杂的判断和较复杂的运算。
        2)标准组件式编程。存储过程被创建后,可以在程序中被多次调用,而不必再重新编写该存储过程的SQL语句。而且数据专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。
        3)实现较快的执行速度。如果某一操作包含大量的transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并给出最终被存储在系统表中的执行计划。而批处理的transaction-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。
        4)减少网络流量。针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的transaction-SQL语句被组织成存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大减少了网络流量并降低了网络负载。
        5)作为一种安全机制来充分利用。系统管理员通过执行某一存储过程的权限进行限制,能够实现对相应数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。
  存储过程思想上很简单,就是数据库SQL语言层面的代码封装与重用。

二、MySQL的存储过程

  MySQL5.0版本开始支持存储过程。大大提高了数据库的处理速度,同时也提高了数据库编程的灵活性。

三、MySQL存储过程创建

  语法:
  delimiter $$	#临时修改SQL语句的结束符,可以自己定义
  CREATE
        [DEFINER = { user | CURRENT_USER }] #指定创建存储过程的用户
     PROCEDURE sp_name ([存储过程参数[,...]]) #声明存储过程
        BEGIN	#存储过程体开始      
      存储过程体
        END     #存储过程体结束
  delimiter; #存储过程创建完成,修改回结束符

  注:
        1)MySQL默认的结束符是';',在创建存储过程时存储过程体中使用';',将会导致存储过程编译过程报错,所以需要先临时修改MySQL的结束符。
        2)存储过程的参数格式:
              [in | out | inout] 参数名 参数类型
        3)存储过程体使用BEGIN和END标识(BEGIN...END可以嵌套使用)。
  例:创建一个删除学生年龄为null的存储过程
        mysql> select * from students;
        +----+-----------+--------+------+
        | id | name      | gender | age  |
        +----+-----------+--------+------+
        |  2 | 李四      |      1 |   19 |
        |  3 | 周芷若    |      2 |   18 |
        |  4 | 赵敏      |      2 |   18 |
        |  5 | Lucy      |      2 |   19 |
        |  6 | Tony      |      1 |   20 |
        |  7 | Lucy      |      2 |   20 |
        |  8 | Tom       |      2 | NULL |
        |  9 | Tom       |      2 | NULL |
        | 11 | Lily      |      2 | NULL |
        | 12 | Tomy      |      2 | NULL |
        | 13 | ZhangSan  |      2 | NULL |
        | 21 | LiLei     |      2 | NULL |
        | 31 | LiLei     |      2 | NULL |
        | 33 | 令狐冲    |      1 | NULL |
        | 34 | 王语嫣    |      2 | NULL |
        | 35 | 小红      |      2 | NULL |
        +----+-----------+--------+------+
        16 rows in set (0.06 sec)

        mysql> delimiter $$
        mysql> create procedure delete_null_age_stu()
        -> begin
        -> delete from students where age is null;
        -> end $$
        Query OK, 0 rows affected (0.05 sec)

        mysql> delimiter ;
        mysql> call delete_null_age_stu();
        Query OK, 10 rows affected (0.20 sec)

        mysql> select * from students;
        +----+-----------+--------+------+
        | id | name      | gender | age  |
        +----+-----------+--------+------+
        |  2 | 李四      |      1 |   19 |
        |  3 | 周芷若    |      2 |   18 |
        |  4 | 赵敏      |      2 |   18 |
        |  5 | Lucy      |      2 |   19 |
        |  6 | Tony      |      1 |   20 |
        |  7 | Lucy      |      2 |   20 |
        +----+-----------+--------+------+
        6 rows in set (0.00 sec)

四、存储过程的参数

  MySQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT,形式如:
  CREATEPROCEDURE 存储过程名([[IN |OUT |INOUT ] 参数名 数据类形...])
  1)IN 输入参数:表示调用者向过程传入值(传入值可以是字面量或变量)
  例:创建存储过程根据传入的参数插入学生信息表
  delimiter $$
  create procedure insert_students(in stu_name varchar(30),in stu_gender int,in stu_age int)
  begin
        insert into students(name,gender,age) values(stu_name,stu_gender,stu_age);
  end $$
  delimiter ;

  call insert_students('萧峰',1,20);

  mysql> select * from students;
  +----+-----------+--------+------+
  | id | name      | gender | age  |
  +----+-----------+--------+------+
  |  2 | 李四      |      1 |   19 |
  |  3 | 周芷若    |      2 |   18 |
  |  4 | 赵敏      |      2 |   18 |
  |  5 | Lucy      |      2 |   19 |
  |  6 | Tony      |      1 |   20 |
  |  7 | Lucy      |      2 |   20 |
  | 37 | 萧峰      |      1 |   20 |
  +----+-----------+--------+------+
  7 rows in set (0.00 sec)

  2)OUT 输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)
  例:创建存储过程,根据传入的学生姓名,科目名称,获取该学生该科目的成绩
  mysql> delimiter $$
  mysql> create procedure get_students_score(in name varchar(30),in subject varchar(20), out score int)
        -> begin
        -> select s.score into score from students stu left join score s on stu.id = s.student_id left join subject su on s.subject_id = su.id where stu.name=name and su.name=subject;
        -> end $$
  Query OK, 0 rows affected (0.25 sec)

  mysql> delimiter ;
  mysql> call get_students_score('周芷若','语文',@score);
  Query OK, 1 row affected (0.00 sec)

  mysql> select @score;
  +--------+
  | @score |
  +--------+
  |     90 |
  +--------+
  1 row in set (0.00 sec)

  3)INOUT 输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)
  例:创建存储过程,传入两个值,返回两个值的2倍和2倍后的总和
  mysql> delimiter $$
  mysql> create procedure inout_param(inout x int,inout y int,out sum int)
        -> begin
        -> set x = x*2;
        -> set y = y*2;
        -> set sum = x+y;
        -> end $$
  Query OK, 0 rows affected (0.11 sec)

  mysql> delimiter ;
  mysql> set @m = 10;
  Query OK, 0 rows affected (0.00 sec)

  mysql> set @n = 20;
  Query OK, 0 rows affected (0.00 sec)

  mysql> call inout_param(@m,@n,@sum);
  Query OK, 0 rows affected (0.00 sec)

  mysql> select @m,@n,@sum;
  +------+------+------+
  | @m   | @n   | @sum |
  +------+------+------+
  |   20 |   40 |   60 |
  +------+------+------+
  1 row in set (0.00 sec)

五、删除存储过程

  语法:
        drop procedure 存储过程名称 # 存储过程每次只能删除一个

六、查看存储过程

  语法:
  show create procedure 存储过程名
  查看所有的存储过程:
  show procedure status;
原文地址:https://www.cnblogs.com/huige185/p/14069092.html