MySQL存储过程

目录

一、存储过程

1.1什么是存储过程

1.2存储过程的优缺点

二、创建存储过程

2.1语法与特性:

2.2声明语句分隔符

2.3过程体的标识

2.4存储过程参数设置

三、存储过程中的变量

四、MySQL变量

五、设置用户执行存储过程的权限

六、查看存储过程的状态

七、查看存储过程的创建代码

八、修改存储过程

九、删除存储过程

十、存储过程的控制语句

十一、IF-ELSEIF-ELSE条件语句

十二、CASE条件语句

十三、WHILE循环语句

十四、LOOP循环语句

十五、REPEAT循环语句

十六、迭代语句

十七 、本章总结


一、存储过程

1.1什么是存储过程

  • Stored Procedure

  • 是一组为了完成特定功能的SQL 语句集合

  • 经编译后保存在数据库中

  • 通过指定存储过程的名字并给出参数的值

  • MySQL5.0版本开始支持存储过程,使数据库引擎更加灵活和强大

  • 可带参数,也可返回结果

  • 可包含数据操纵语句、变量、逻辑控制语句等MySQL存储过程_第1张图片

1.2存储过程的优缺点

优点

  1. 减少网络流量

  2. 提升执行速度

  3. 减少数据库连接次数

  4. 安全性高

  5. 复用性高

缺点

  • 可移植性差

经验

  • 在实际应用开发中,要根据业务需求决定是否使用存储过程,对于应用中特别复杂的数据处理,可以选用存储过程来进行实现

  • 例如:复杂的报表统计,涉及多条件多表的联合查询等

二、创建存储过程

2.1语法与特性:

语法:

CREATE PROCEDURE 过程名 ([过程参数[,…]])
    [特性] #可选项,用于设置存储过程的行为
    存储过程体  

常用特性:MySQL存储过程_第2张图片

2.2声明语句分隔符

  • 使用DELIMITER关键字将分隔符设置为“$$”或“//”

DELIMITER $$  
#或者  
DELIMITER //
  • 还原为默认分隔符“;”

DELIMITER ; 

2.3过程体的标识

  • 定义存储过程的过程体时,需要标识开始和结束

    BEGIN
        # … 
    END
    DELIMITER ; #END后,必须使用DELIMITER语句中设置的分隔符为结束

注意事项:

//如果没有声明分隔符,编译器会将其视为普通SQL语句进行处理,编译过程会报错
//正确用法:首先用DELIMITER关键字声明当前段的分隔符,最后要将分隔符还原为默认字符

示例:

#如果存在则删除
drop procedure if exists proc_patient_countPatient; 
delimiter//      #声明分隔符
create procedure proc_patient_countPatient()
begin #过程体开始 
    select count(0) as totalCount from patient;
end// #过程体结束 
delimiter;       #恢复默认分割符
​
#调用
call proc_patient_countPatient();

2.4存储过程参数设置

定义存储过程的参数

语法:

[IN | OUT | INOUT] 参数名 数据类型

示例:

DELIMITER //      #声明分隔符
CREATE PROCEDURE proc_patient_countPatient2(OUT patientNum INT)
    #省略...
DELIMITER ;      #恢复默认分隔符

注意:

  • 如果需要定义多个参数,需要使用“,”进行分隔

IN:指输入参数

  • 该参数的值必须在调用存储过程时指定

  • 存储过程中可以使用该参数,但它不能被返回

OUT:指输出参数

  • 该参数可以在存储过程中发生改变,并可以返回

INOUT:指输入输出参数

  • 该参数的值在调用存储过程时指定

  • 在存储过程中可以被改变和返回

调用执行存储过程

CALL 存储过程名([参数1,参数2, …]);

存储过程调用类似于Java中的方法调用

call proc_patient_countPatient();

三、存储过程中的变量

与Java语言类似,定义存储过程时可以使用变量

DECLARE 变量名[,变量名...] 数据类型 [DEFAULT 值];

给变量进行赋值

SET 变量名 = 表达式值[,变量名=表达式...] ;
  • 声明交易时间变量trade_time,并设置默认值为2020-07-10

DECLARE trade_time date DEFAULT '2020-07-10';
  • 设置变量total的值为100

SET total=100;
  • 注意事项:

定义存储过程时,所有局部变量的声明一定要放在存储过程体的开始;否则,会提示语法错误

四、MySQL变量

系统变量

  • 指MySQL全局变量,以“@@”开头,形式为“@@变量名”

  • 用户自定义变量

    • 局部变量

      • 一般用于SQL的语句块中,如:存储过程中的BEGIN和END语句块

      • 作用域仅限于定义该变量的语句块内

      • 生命周期也仅限于该存储过程的调用期间

      • 在存储过程执行到END时,局部变量就会被释放

  • 会话变量

    • 是服务器为每个客户端连接维护的变量,与MySQL客户端是绑定的

    • 也称作用户变量

    • 可以暂存值,并传递给同一连接中其他SQL语句进行使用

    • 当MySQL客户端连接退出时,用户变量就会被释放

    • 用户变量创建时,一般以“@”开头,形式为“@变量名”

五、设置用户执行存储过程的权限

通过DEFINER和SQL SECURITY特性控制存储过程的执行权限

语法:

CREATE
    [DEFINER = { user | CURRENT_USER }]  #定义DEFINER,默认为当前用户
PROCEDURE 存储过程名
    [SQL SECURITY { DEFINER | INVOKER } | …]#指定DEFINER或INVOKER权限
BEGIN
    …
END

DEFINER

  • 默认DEFINER = CURRENT_USER

  • 检查 ‘user_name’@‘host_name’ 的权限

INVOKER

  • 执行存储过程时,会检查调用者的权限

注意事项:

  • 如果省略sql security特性,则使用definer属性指定调用者,且调用者必须具有EXECUTE权限,必须在mysql.user表中

  • 如果将sql security特性指定为invoker,则definer属性无效

六、查看存储过程的状态

查看数据库中已创建的存储过程

语法:

show procedure status;

查看hosptal数据库中创建的存储过程

#指定数据库名查询存储过程
show procedure status where DB = 'hospital';
#使用LIKE关键字匹配存储过程名称
show procedure status like '%patient%';

七、查看存储过程的创建代码

查看数据库中已创建的存储过程代码

SHOW CREATE PROCEDURE 存储过程名;

八、修改存储过程

使用ALTER PROCEDURE语句修改创建存储过程时定义的特性

ALTER PROCEDURE 存储过程名 [特性……] ;

经验

  • 使用ALTER 关键字只能修改存储过程的特性,如果想修改存储过程中过程体的内容,需先删除该存储过程,再进行重新创建
  • 在Navicat中,修改存储过程的内容后,可以直接保存

九、删除存储过程

使用DROP PROCEDURE语句删除已创建的存储过程

DROP PROCEDURE 存储过程名;

删除已创建的存储过程proc_patient_countPatient

drop procedure if exists;

注意:

  • 创建存储过程前,可以使用IF EXISTS语句检查其是否已存在,如果不存在,再进行创建

十、存储过程的控制语句

与Java语言的流程控制语句类似,MySQL提供的控制语句

条件语句

  1. IF-ELSEIF-ELSE条件语句

  2. CASE条件语句

循环语句

  1. WHILE循环

  2. LOOP循环

  3. REPEAT循环

迭代语句

十一、IF-ELSEIF-ELSE条件语句

语法:

IF 条件 THEN 语句列表
   [ELSEIF 条件 THEN 语句列表]
   [ELSE 语句列表]
END IF;

十二、CASE条件语句

语法1:

CASE
   WHEN 条件 THEN 语句列表
   [WHEN 条件 THEN 语句列表]
   [ELSE 语句列表]
END CASE;

语法2:

CASE 列名
   WHEN 条件值 THEN 语句列表
   [WHEN 条件值 THEN 语句列表]
   [ELSE 语句列表]
END CASE;

注意:在某种情况下(例如,做等值判断),使用第二种写法更加简洁但是,因为CASE后面有列名,功能上会有一些限制

十三、WHILE循环语句

首先判断条件是否成立。如果成立,则执行循环体

[label:] WHILE 条件 DO
   语句列表
END WHILE [label]

  • label为标号,用于区分不同的循环,可省略

    • 用在begin、repeat、while 或者loop 语句前

假设有测试表test,有Id字段、Val字段

根据输入的行数要求,批量插入测试数据

十四、LOOP循环语句

不需判断初始条件,直接执行循环体

[label:] LOOP
   语句列表
END LOOP [label] ;

遇到LEAVE语句,退出循环

leave lable

十五、REPEAT循环语句

先执行循环操作再判断循环条件

#与Java的do-while循环语句类似
[label:] REPEAT 
   语句列表
UNTIL 条件
END REPEAT [label]

与LOOP循环语句相比较

  • 相同点:不需要初始条件直接进入循环体

  • 不同点:REPEAT语句可以设置退出条件

使用REPEAT循环语句编码实现

  • 根据输入的行数要求,向测试表test中批量插入测试数据

十六、迭代语句

从当前代码处返回到程序块开始位置,重新执行

ITERATE label;

  • ITERATE关键字可以嵌入到LOOP、WHILE和REPEAT程序块中

十七 、本章总结

MySQL存储过程_第3张图片

详细的mysql存储过程参考MySQL 05 存储过程_众生云海,一念初见的博客-CSDN博客_mysql5 存储过程

你可能感兴趣的:(mysql,数据库,mysql)