文章目录

  • 存储过程
  • 分类
  • 存储例程
  • 存储函数
  • 存储过程
  • 触发器
  • 事件
  • 游标
  • 参考文献


存储过程

分类

springboot mysql 存储过程返回结果集 mysql存储过程有返回值吗_触发器

存储例程

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

存储函数

存储过程

return语句

必须有

可以有

返回值个数

1个

>=1个

参数类型

in

in(默认) 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

springboot mysql 存储过程返回结果集 mysql存储过程有返回值吗_存储过程_02

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 存储程序(五)之触发器和事件简介

MYSQL中的异常处理