mysql_存储过程

什么是存储过程:

  是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,它存储在数据库中,一次编译后永久有效,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。在数据量特别庞大的情况下利用存储过程能达到倍速的效率提升。

 

优点

  1、在生产环境下可以直接修改存储过程来修改业务逻辑(或者bug),不用重启服务器;

  2、执行速度快,存储过程经过编译之后会比单条sql一条一条执行速度要快;

  3、减少网络传输流量;

  4、方便优化; 

缺点

  1、过程化编程,维护成本高;(比如复杂存储过程后续新人员进行维护会看不懂)

  2、调试不便;

  3、数据库移植性较差;(数据库直接语法可能不同);

 

数据库中存储过程必须要进行创建,就像创建表一样,后续再执行;MYSQL中创建后的存储过程在 函数 列中可以看到,MYSQL后续更新存储过程需要先删除原先的存储过程,在创建新存储过程;

 

语法:

存储过程结束符:

  正常sql语句会将分号 ;作为sql语句结束符,存储过程中也是如此,分号;会作为sql语句结束符,但存储过程结束符需要自定义,使用 delimiter关键字,后面接 自定义符号

  关键字 delimiter

  自定义符号 $$

delimiter $$ -- 自定义$$符号作为存储过程结束符号

 

存储过程基本结构:

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

CREATE  PROCEDURE:是用来创建存储过程的关键字,

sp_name:存储过程名称

proc_parameter:指定存储过程的参数列表,列表如下

[ IN | OUT | INOUT ]  param_name  type

其中,IN是输入参数,out是输出参数 ,INOUT是即可输入也可输出,param_name  是参数名称,type是参数类型。

 

characteristic:指定存储过程的特性,有以下取值。

1)LANGUAGE  SQL :说明routine_body部分是由SQ语句组成的,sql是LANGUAGE  特性的唯一值。

2)[ NOT ] DETERMINISTIC :指明存储过程执行的结果是否正确。DETERMINISTIC 表示结果是确定的,当执行存储过程时,

相同的输入会得到相同的输出。NOT   DETERMINISTIC 表示结果是不确定的,相同的输入可能得到不同的结果,如果没有指定任意一个值,

默认为NOT   DETERMINISTIC

3){CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA}: 指明子程序是SQL语句的限制。

CONTAINS SQL: 是表明子程序包含SQL语句,但是不包含读或是写数据的语句

NO SQL:表明子程序不包含SQL语句

 READS SQL DATA: 表明子程序包含读数据的语句

MODIFIES SQL DATA:表明子程序包含写数据的语句

默认情况下,系统会指定为CONTAINS SQL

4)SQL SECURITY { DEFINER | INVOKER } ; 指明谁有权限来执行,

DEFINER  表明只有定义者才有执行

INVOKER :表明拥有权限的调用者可以执行。默认情况下指定为DEFINER  。

5)COMMENT 'string ' :注释信息,可以用来描述存储过程或是函数,

routine_body是SQL代码块的内容,可以用BEGIN....END 来表示SQL代码的开始和结束。

    

存储过程可能需要复杂的SQL,并且需要创建存储过程的权限。但是使用存储过程将简化操作,减少冗余的操作,

还可以减少操作过程的失误,提高效率。

 

创建第一个基本存储过程:

delimiter $$ CREATE PROCEDURE hello_world() BEGIN     SELECT 'Hello World'; END $$
CALL hello_world;-- 执行当前存储过程

 

变量及其赋值 

局部变量:当前存储过程中有效

DECLARE(局部变量定义)、SET(赋值)、INTO(赋值)

语法结构:

-- DECLARE、SET、INTO DECLARE 变量名 TYPE [DEFAULT 默认值]; -- 声明一个局部变量并设置默认值 SET 变量名 = 值;                                            -- 对当前局部变量赋值 SELECT t.name into 变量名 from table t where id = '1'; -- 将表table中的name字段值赋值给变量名

示例:

delimiter $$ CREATE PROCEDURE hello_world() BEGIN     DECLARE testname VARCHAR(32) DEFAULT 'ZS';     SELECT testname;     SET testname = 'LS';     SELECT testname; END $$  CALL hello_world; -- 执行存储过程 DROP PROCEDURE hello_world; -- 删除存储过程
delimiter $$ CREATE PROCEDURE sp1() BEGIN     DECLARE testname VARCHAR(32) DEFAULT 'ZS';     SELECT m.name into testname from module as m where id = '1'; -- 将表module中的name值使用into关键字赋值给testname     SELECT testname; END $$

 

用户变量:用户自定义,当前会话连接即有效

语法结构:@变量名:不需要声明,使用即声明

delimiter $$ CREATE PROCEDURE sp2() BEGIN     SET @test_name = 'ww';     SELECT @test_name; END $$  CALL sp2; -- 执行存储过程 SELECT @test_name; -- 查询用户变量@test_name

 

会话变量:由系统提供,当前会话连接有效

语法结构:@@SESSION.系统变量名

SHOW SESSION VARIABLES; -- 查看当前会话变量 SELECT @@GLOBAL.auto_increment_increment; -- 查询某会话变量 SET @@SESSION.auto_increment_increment = 1; -- 修改当前某会话变量 SHOW SESSION VARIABLES like '%char%'; -- 查看当前会话变量并进行模糊查询

 

全局变量:整个mysql服务器有效

语法结构:@@GLOBAL.系统变量名

SHOW GLOBAL VARIABLES; -- 查看当前系统变量 SELECT @@GLOBAL.auto_increment_increment; -- 查询某系统变量 SHOW GLOBAL VARIABLES like '%char%'; -- 查看当前系统变量并进行模糊查询

 

入参出参

语法结构:

-- IN 输入参数 -- OUT 输出参数 -- 输入输出参数 IN | OUT | INOUT 参数名 类型;

示例:

delimiter $$ CREATE PROCEDURE sp1(IN var1 VARCHAR(10),OUT var2 VARCHAR(10),INOUT var3 VARCHAR(20)) BEGIN         SET var2 = var1;         -- CONCAT 字符串拼接函数         SELECT CONCAT(var1,var3); END $$  SET @var3 = 'world'; CALL sp1('hello',@var2,@var3); -- 执行存储过程 SELECT @var2; SELECT @var3;

 

流程控制-判断

IF-ELSE 

语法结构:

IF 条件判断 THEN 执行语句     [ELSEIF 条件判断 THEN 执行语句]     ...     [ELSE 执行语句] END IF

 

 CASE

 语法结构一:

CASE 变量名     WHEN 期望值 THEN 执行语句;     WHEN 期望值 THEN 执行语句;     ...     ELSE 执行语句; END CASE

语法结构二:

CASE 变量名     WHEN 判断语句 THEN 执行语句;     WHEN 判断语句 THEN 执行语句;     ...     ELSE 执行语句; END CASE

 

流程控制:循环

 

参考:

https://www.cnblogs.com/lanpo/articles/11628836.html

https://www.bilibili.com/video/BV1q64y1T7Uh?p=2

0:49:40 未完待续。。。