zoukankan      html  css  js  c++  java
  • 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;
  • 相关阅读:
    【BZOJ1046】[HAOI2007]上升序列
    【BZOJ1045】[HAOI2008]糖果传递
    【BZOJ1044】[HAOI2008]木棍分割
    【BZOJ1041】[HAOI2008]圆上的整点
    【LG2257】YY的GCD
    【BZOJ1018】[SHOI2008]堵塞的交通
    【LG4735】最大异或和
    【POJ2182】Lost Cows
    【POJ2482】Stars in Your Window
    【POJ1733】Parity game
  • 原文地址:https://www.cnblogs.com/huige185/p/14069092.html
Copyright © 2011-2022 走看看