Bootstrap

mysql_存储例程(存储函数 存储过程 触发器 事件 游标)

存储过程

分类

在这里插入图片描述

存储例程

本质上也是封装了一些可执行的语句,只不过它的调用方式是显示调用。存储例程可分为存储函数和存储过程。两者间区别如下:

存储函数存储过程
return语句必须有可以有
返回值个数1个>=1个
参数类型inin(默认) out inout
显示执行过程中的select不会显示执行过程中的select会显示
调用可以直接在表达式和SQL语句中调用只能用CALL语句显示调用

其中,存储过程不需要返回值,而存储函数必须有返回值。另外,存储过程在执行查询语句时产生的所有结果集,全部将会被显示到客户端。

存储函数

  • 定义

    CREATE FUNCTION 存储函数名称([参数名 数据类型]组成的参数列表) comment ‘函数的注释说明’ 
    RETURNS 返回值类型
    BEGIN
        函数体内容
        -- 函数体中,每条语句都要以分号;结尾
        -- 函数体内容可以包含:
        -- 1. SQL语句,如:
        -- 2. 变量定义(此时变量的定义用declare,不加@)和赋值
           DECLARE 变量名 数据类型 [DEFAULT 默认值];  -- 不声明默认值时,默认值为NULL 
           set 变量名 = 变量/;
        -- 3. 流程控制语句
           -- 3.1 条件语句
              if 布尔表达式 then
                 处理语句
              elseif 布尔表达式 then
                 处理语句
              else 
                 处理语句
              end if;
           -- 3.2 循环语句
              -- 方式1
              while 布尔表达式 do
                 循环语句
              end while;
              -- 方式2
              repeat
                 循环语句
              until 布尔表达式 end repeat;
              -- 方式3
              循环标记:loop
                 循环语句
                 leave 循环标记; -- leave语句一般和判断语句一起用,用来退出循环
              end loop 循环标记
        
    END
    

    例子:

    create function avg_score(s varchar(100))
    return double
    begin
        declare c int default 1;
        set c = s;
    	return (select avg(score) from student_score where subject = s)
    end $
    
  • 调用

    自定义的函数和系统内置函数的使用方式是一样的。直接利用函数名()即可
    在这里插入图片描述

  • 查看

    -- 查看定义的函数有哪些
    SHOW FUNCTION STATUS [LIKE 需要匹配的函数名]
    -- 查看某个函数的具体定义
    SHOW CREATE FUNCTION 函数名
    
  • 删除

    DROP FUNCTION 函数名
    

存储过程

  • 定义

    CREATE PROCEDURE 存储过程名称([参数类型 参数名 数据类型]组成的参数列表)
    -- 存储过程的参数类型有三种:in out inout
    -- in:实参可为常量/变量;实参为变量时,只能向外赋值,不能被赋值(即in型参数的值不会被存储过程更改)
    -- out:实参只能是变量;实参不能向外赋值,只能被赋值
    -- inout:实参只能是变量;实参既可向外赋值,又可被赋值
    BEGIN
        需要执行的语句,可包含内容和存储函数是一样的。
    END    
    

    例子:

    create procedure t1_operation(m1_value int, n1_value char(1))
    begin
    	select * from t1;
    	insert into t1(m1,n1) values(m1_value,n1_value);
    	select * from t1;
    end $
    
  • 调用

    call 存储过程([参数列表]);
    
  • 查看

    -- 查看定义的存储过程有哪些
    SHOW PROCEDURE STATUS [LIKE 需要匹配的函数名]
    -- 查看某个存储过程的详细定义
    SHOW CREATE PROCEDURE 存储过程名称
    
  • 删除

    DROP PROCEDURE 存储过程名称
    

触发器

触发器的作用就是,在对某个表格进行某项操作(增删改)之前或之后,自动地(即被服务器隐性调用)对操作所涉及的记录执行触发器操作。

  • 定义

    -- 竖线"|"分隔的语句表示必须在给定的选项中选取一个值
    CREATE TRIGGER 触发器名
    {BEFORE|AFTER}          
    {INSERT|DELETE|UPDATE}
    ON 表名
    FOR EACH ROW 
    BEGIN
        触发器操作
    END
    

    CREATE TRIGGER 触发器名

    触发器名字一般的命名规则为:“b/a”+“i/d/u”+"_"+“表名”,例如 bi_t1 ,表示对表 t1 设置 before insert 类型的触发器。

    BEFORE AFTER

    在这里插入图片描述

    INSERT DELETE UPDATE

    MySQL中目前只支持对INSERT、DELETE、UPDATE这三种类型的语句设置触发器。

    FOR EACH ROW

    表示触发器作用范围为增删改操作涉及的记录

    • 对于INSERT,FOR EACH ROW影响的记录就是我们准备插入的那些新记录。
    • 对于DELETE和UPDATE,FOR EACH ROW影响的记录就是符合WHERE条件的那些记录(如果语句中没有WHERE条件,那就是代表全部的记录)。

    BEGIN ... END

    表示触发器需要执行的操作。其中,不能有输出结果集相关的语句,如select。

    此外,触发器使用"new""old"来表示原表中不存在和已存在的记录。其中,

    • 对于INSERT语句设置的触发器来说,NEW代表准备插入的记录,不会使用OLD
    • 对于DELETE语句设置的触发器来说,OLD代表删除前的记录,不会使用NEW
    • 对于UPDATE语句设置的触发器来说,NEW代表修改后的记录,OLD代表修改前的记录。

    例子

    create trigger bi_ti
    before insert on t1
    for each row
    begin
    	if new.m1<1 then
    		set new.m1 =1;
    	elseif new.m1>10 then
    		set new.m1 = 10;
    	end if;
    end $
    
  • 调用

    触发器的调用,在对表格执行增删改操作时,自动执行。

  • 查看

    -- 查看数据库中有哪些触发器
    show triggers
    -- 查看某个触发器的定义
    show create trigger 触发器名;
    
  • 删除

    drop trigger 触发器名;
    

事件

事件可以实现,自动地(即被服务器隐性调用)在某个时间点或者某隔一段时间执行一次某些命令。

  • 定义

    CREATE EVENT 事件名
    ON SCHEDULE
    {AT 某个确定的时间点 | EVERY 期望的时间间隔 [STARTS datetime][END datetime]}
    DO
    BEGIN
        具体的语句
    END
    

    例子:

    -- 指定某个时间点执行
    CREATE EVENT insert_t1
    ON SCHEDULE
    AT '2018-03-10 15:48:54'
    -- 也可以写成:AT DATE_ADD(NOW(), INTERVAL 2 DAY)
    DO
    BEGIN
        INSERT INTO t1(m1, n1) VALUES(6, 'f');
    END
    
    -- 指定某个时间间隔执行
    CREATE EVENT insert_t1
    ON SCHEDULE
    EVERY 1 HOUR STARTS '2018-03-10 15:48:54' ENDS '2018-03-12 15:48:54'
    -- 也可以写成:EVERY 1 HOUR 
    DO
    BEGIN
        INSERT INTO t1(m1, n1) VALUES(6, 'f');
    END
    
  • 调用

    事件会被服务器,在相应的时间设定下,被自动调用。

    事件的自动调用需要在服务器中开启:

    -- 启动mysql服务器时,开启事件监听
    event_scheduler = ON
    -- 开启mysql服务器后,通过设置mysql服务器的环境变量,开启事件监听
    set global event_scheduler = ON
    
  • 查看

    -- 查看数据库定义的事件
    SHOW EVENTS;
    -- 查看某个事件具体创建命令
    SHOW CREATE EVENT 事件名;
    
  • 删除

    DROP EVENT 事件名;
    

游标

类似于迭代器,用来标记结果集中正在访问的某一行记录,初始状态下它标记结果集中的第一条记录,每次使用后自动移动到下一条记录的位置。

游标可以用在存储函数中和存储过程中时,游标的创建、打开、调用和关闭,均在存储函数和存储过程中完成。

  • 创建

    DECLARE 游标名称 CURSOR FOR 查询语句; -- 注意,创建游标的语句必须放在变量声明的后面
    
  • 打开

    打开游标意味着执行查询语句,让创建好的游标与该查询语句得到的结果集关联起来。

    open 游标名称;
    
  • 调用

    把指定游标对应记录的各列的值依次赋值给INTO后边的各个变量。赋值后,游标自动移动到下一条记录的位置。

    -- fetch语句一般用在循环语句中
    FETCH 游标名 INTO 变量1, 变量2, ... 变量n
    
  • 关闭

    关闭游标意味着会释放该游标占用的内存。

    close 游标名称;
    
  • 例子

    CREATE PROCEDURE cursor_demo()
    BEGIN
        -- 声明变量
        DECLARE m_value INT;
        DECLARE n_value CHAR(1);
        DECLARE not_done INT DEFAULT 1;
    
        -- 声明游标
        DECLARE t1_record_cursor CURSOR FOR SELECT m1, n1 FROM t1; 
    
        -- 在游标遍历完记录的时候将变量 not_done 的值设置为 0,并且继续执行后边的语句
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET not_done = 0;  
    
        -- 打开游标
        OPEN t1_record_cursor;
    
        WHILE not_done = 1 DO
            -- 使用游标
            FETCH t1_record_cursor INTO m_value, n_value;
            SELECT m_value, n_value, not_done;
        END WHILE;
    
        CLOSE t1_record_cursor;
    END
    

参考文献

https://mp.weixin.qq.com/s?__biz=MzIxNTQ3NDMzMw==&mid=2247483968&idx=1&sn=08a4072e046cc7833b60cc9d66298ec8&scene=19#wechat_redirect 存储程序(二)之存储函数简介

https://mp.weixin.qq.com/s?__biz=MzIxNTQ3NDMzMw==&mid=2247483972&idx=1&sn=4b9cc8c88eea19fd726fc61738d7acea&scene=19#wechat_redirect 存储程序(三)之存储过程简介

https://mp.weixin.qq.com/s?__biz=MzIxNTQ3NDMzMw==&mid=2247483976&idx=1&sn=f39ffa2f4388f1f6b593bfeb1094c5a4&scene=19#wechat_redirect 存储程序(四)之游标简介

https://mp.weixin.qq.com/s?__biz=MzIxNTQ3NDMzMw==&mid=2247483980&idx=1&sn=3a3811cf19fadf87f326ad71c3b6f20a&scene=19#wechat_redirect 存储程序(五)之触发器和事件简介

https://www.cnblogs.com/aixinyiji/p/11038635.html MYSQL中的异常处理

;