zoukankan      html  css  js  c++  java
  • 史上最简单MySQL教程详解(进阶篇)之存储过程(一)

    史上最简单MySQL教程详解(进阶篇)之存储过程(一)

    什么是存储过程

    SQL基本是一个命令实现一个处理的,是不能编写处理流程的。虽然通过子查询、多表连接等方式能实现一些高级的功能,但是具有很大的局限性。对于SQL本身是很难实现针对不同条件进行不同的处理或者循环等功能。即使能够实现,也是十分复杂或者对于性能有极大的影响。存储过程(Stored Procedure)就应运而生,它可以由SQL语句和各种条件判断、循环控制等语句组成,简单的说:存储过程像相互之间有联系的SQL语句组成的“小程序”。因为SQL的执行是需要经历一个:解析->编译->执行的过程的。存储过程是提前经过解析和编译存储在数据库中的,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。

    存储过程的作用

    • 提高执行性能:

      因为存储过程是提前创建并保存在数据库中的,当执行命令时,就能免去解析和编译的过程,能减轻数据库的负担,提高执行性能。

    • 可减轻网络负担:

      因为存储过程的执行,只需要客户端传递对应的参数即可,并不需要多次传递SQL命令本身,可以大大的减轻网络负担,减少彼此之间的通信量,整体提高数据库性能。

    • 提高数据库的安全性:

      存储过程禁止了对表本身的访问,只赋予用户对相关存储过程的访问权限。同时存储过程将数据处理部分“黑匣子化”后,程序本身的可读性和简洁性都会有所增加。用户不需要考虑存储过程的内部实现,只需要知道应该调用哪个存储过程即可。

    如何使用存储过程

    创建存储过程

    创建存储过程使用的是【CREATE】语句,具体语法如下:

    CREATE PROCEDURE 存储过程名(
        参数1的种类 参数名1 参数1的数据类型,
        参数2的种类 参数名2 参数2的数据类型
    )
    BEGIN 
        数据处理过程
    END

    上面提到的参数种类,主要分为下面三种类型:

    参数种类 说明
    IN 输入参数(可省略)
    OUT 输出参数
    INOUT 既是输出参数,也是输入参数

    对于参数的数据类型,可参考这篇博文: 史上最简单MySQL教程详解(基础篇)之常用表操作和表参数介绍

    在创建存储过程之前呢,还有下面几个要点需要掌握。

    DELIMITER改变分隔符

    【DELIMITER】是MySQL用来改变监视器中分离符的命令。默认的分隔符是【;】,但是,存储过程本身就是命令的集合,所以一定还会含有其他的分隔符。那么它们彼此之间冲突和混淆,所以在创建存储过程之前,我们需要将默认符换成一个完全无关的符号,只要不与其他关键字发生歧义即可,通常使用的是【//】。在完成创建之后,我们再将其回复即可。但需要提醒的是:分隔符的改变只会在启动期间有效,重新启动后,会自动恢复到默认状态。

    可使用的控制语句

    1. 简单分支

      IF 条件表达式1
      条件表达式1TRUE时执行的命令
      [ELSEIF 条件表达式N
         条件表达式N为TRUE时执行的命令
      ]
      [ELSE
         全部为False时执行的命令
      ]
      END IF
    2. 多重分支

      CASE 表达式1
      WHEN 值1 THEN 表达式1 = 值1时执行的命令
      ...
      WHEN 值N THEN 表达式1 = 值N时执行的命令
      [ELSE 上述所有值以外执行的命令]
      END CASE
    3. 循环控制(后置判断)

      REPEAT
      直至条件表达式为True时执行的命令
      UNTIL 
      条件表达式 
      END REPEAT
    4. 循环控制(前置判断)

      WHILE 条件表达式 DO
      系列命令
      END WHILE

    开始创建存储过程

    mysql> DELIMITER //
        -> CREATE PROCEDURE sp_student (IN p_name VARCHAR(20))
        -> BEGIN
        ->  IF p_name IS NULL OR p_name = "" THEN 
        ->      SELECT * FROM student ;
        ->  ELSE 
        ->      SELECT * FROM student WHERE studentName LIKE p_name;
        ->  END IF ;
        -> END 
        -> //
    Query OK, 0 rows affected
    mysql> DELIMITER ;

    这样我们就创建了一个【sp_student】的存储过程。如果我们传入参数【p_name】,那么他就会进行模糊查询,否则就无条件查询。

    确认存储过程

    我们确认存储过程使用的是【SHOW】语句,具体语法如下:

    SHOW PROCEDURE STATUS G

    例如:

    mysql> SHOW PROCEDURE STATUS G
    *************************** 27. row ***************************
                      Db: test1
                    Name: sp_student
                    Type: PROCEDURE
                 Definer: root@localhost
                Modified: 2018-09-13 12:03:13
                 Created: 2018-09-13 12:03:13
           Security_type: DEFINER
                 Comment:
    character_set_client: utf8
    collation_connection: utf8_general_ci
      Database Collation: utf8_unicode_ci
    27 rows in set (0.00 sec)

    结果集参数解释:

    参数 说明
    Db 所属数据库名
    Name 存储过程名
    Type 种类(PROCEDURE:存储过程/FUNCTION:函数)
    Definer 创建者
    Modified 最终更新时间
    Created 创建时间
    Security_type 安全种类(DEFINER:存储过程权限与创建用户权限一致)
    Comment 备注
    character_set_client 从客户端发送过来查询的字符编码
    collation_connection 当前连接中使用的校对顺序
    Database Collation 数据库的校对顺序

    除此之外,还能使用下面的语句确认:

    SHOW CREATE PROCEDURE 存储过程名G

    例如:

    mysql> SHOW CREATE PROCEDURE sp_studentG
    *************************** 1. row ***************************
    Procedure: sp_student
    sql_mode: STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER
        Create Procedure: CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_student`(IN p_name VARCHAR(20))
    BEGIN
    
    IF p_name IS NULL OR p_name = "" THEN
    
    SELECT * FROM student ;
    
    ELSE
    
    SELECT * FROM studnet WHERE studentName LIKE p_name;
    
    END IF ;
    
    END
    character_set_client: utf8
    collation_connection: utf8_general_ci
    Database Collation: utf8_unicode_ci
    1 row in set (0.00 sec)

    这个会返回一些安全的设置信息,并且名称都会被单引号(‘ ’)括起来。

    使用存储过程

    使用存储过程,使用的是【CALL】命令,具体语法如下:

    CALL 存储过程名(参数1,...);

    例如:

    mysql> CALL sp_student('路人%');    //提交了参数
    +-----------+-------------+--------------+----------------+
    | studentId | studentName | studentPhone | studentAddress |
    +-----------+-------------+--------------+----------------+
    | 4         | 路人甲      | 132          | 广州           |
    | 5         | 路人乙      | 118          | 深圳           |
    +-----------+-------------+--------------+----------------+
    2 rows in set
    
    Query OK, 0 rows affected
    
    mysql> CALL sp_student('');    //未提交参数
    +-----------+-------------+--------------+----------------+
    | studentId | studentName | studentPhone | studentAddress |
    +-----------+-------------+--------------+----------------+
    | 1         | 张三        | 140          | 重庆           |
    | 2         | 李四        | 137          | 北京           |
    | 3         | 王五        | 135          | 上海           |
    | 4         | 路人甲      | 132          | 广州           |
    | 5         | 路人乙      | 118          | 深圳           |
    +-----------+-------------+--------------+----------------+
    5 rows in set
    Query OK, 0 rows affected
    

    删除存储过程

    删除已经创建的存储过程使用【DROP】语句,具体语法如下:

    DROP PROCEDURE 存储过程名;

    例如:

    mysql> DROP PROCEDURE sp_student;
    Query OK, 0 rows affected (0.00 sec)

    参考文献:

    MySQL存储过程详解

    《MySQL高效编程》

    别忘了关注博主的个人公众号,有更多精彩内容、资源分享~

  • 相关阅读:
    简单的PHP+SMARTY分页类
    三大WEB服务器对比分析(apache ,lighttpd,nginx)
    逐步设置vim C/C++语法高亮显示和自动缩进
    Lighttpd 的安装配置(web服务器软件)
    ASP如何获取文件和目录空间大小
    innerHtml用法
    临时表操作的一些见解(解决了我在存储过程中使用临时表的困惑)
    Javascript的IE和Firefox兼容性汇编
    Javascript的IE和Firefox兼容性汇编
    innerHtml用法
  • 原文地址:https://www.cnblogs.com/newtol/p/10159087.html
Copyright © 2011-2022 走看看