Mysql存储过程、触发器、事件调度器使用入门指南


Posted in MySQL onJanuary 22, 2022

存储过程(Stored Procedure)是一种在数据库中存储复杂程序的数据库对象。为了完成特定功能的SQL语句集,经过编译创建并保存在数据库中。

一、存储过程的简单使用

创建存储过程

create procedure test()
begin
    select * from users;
end;

调用存储过程

call test();

二、存储过程中的变量

create procedure test()
begin

  -- 使用 declare语句声明一个变量
  declare username varchar(32) default '';
  
  -- 使用set语句给变量赋值
  set username='xiaoxiao';
  
  -- 将users表中id=1的名称赋值给变量username
  select name into username from users where id=1;
  
  -- 返回变量
  select username;
end;

注意:

  • 变量可以通过set来赋值,也可以通过select into的方式赋值;
  • 变量需要返回,可以使用select语句,如:select 变量名。

三、变量的作用域

存储过程的作用域在begin和end块之间,变量声明在begin之外,可以作为全局变量使用:

create procedure test()
    begin
      declare userscount int default 0; -- 用户表中的数量
      begin
            select count(*) into userscount from users;
            select userscount; -- 返回用户表中的数量
      end;
      begin 
        declare maxmoney int default 0; -- 最大金额
        select max(money) into maxmoney from orders;
        select userscount,maxmoney; -- 返回用户表中的数量、最大金额
       end;
    end;

四、存储过程参数

create procedure 名称([IN|OUT|INOUT] 参数名 参数数据类型 )
begin
......
end

IN: 传入参数(不指定时,默认就是IN类型)

create procedure test(userId int)
    begin
        declare username varchar(32) default '';
        select name into username from users where id=userId;
        select username;
    end;

OUT:传出参数

create procedure test(in userId int,out username varchar(32))
   begin
     select name into username from users where id=userId;
   end;

INOUT: 既是传入又是传出参数

create procedure test6(inout userId int,inout username varchar(32))
begin
    set userId=2;
    set username='';
    select id,name into userId,username from users where id=userId;
end;

五、逻辑控制语句

1、条件语句

if() then...
elseif() then...
else ...
end if;
create procedure test(in userid int)
begin
   declare my_status int default 0;
   select status into my_status from users where id=userid;
   
   if(my_status=1)
   then 
       update users set score=score+10 where id=userid;
   elseif(my_status=2)
   then 
       update users set score=score+20 where id=userid;
   else 
       update users set score=score+30 where id=userid;
   end if;
end;

2、循环语句

(1)while

while(表达式) do 
   ......  
end while;
create procedure test()
begin
  declare i int default 0;
  while(i<10) do 
     begin 
        select i;
        set i=i+1;
        insert into test1(id) values(i);
     end;
  end while;
end;

(2)repeat

repeat...until...end repeat;

只有当until为真是才跳出循环:

create procedure test()
begin
    declare i int default 0;
    repeat 
     begin 
        select i;
        set i=i+1;
        insert into test1(id) values(i);
     end;
    until i>=10 -- 如果i>=10,则跳出循环
    end repeat;
end;

3、case分支

case ...
when ... then....
when.... then....
else ... 
end case;
create procedure testcate(userid int)
    begin 
        declare my_status int default 0;
        select status into my_status from users where id=userid;
 
        case my_status
            when 1 then update users set score=10 where id=userid;
            when 2 then update users set score=20 where id=userid;
            when 3 then update users set score=30 where id=userid;
            else update users set score=40 where id=userid;
        end case;
    end;

六、游标

游标保存了查询结果的临时区域

declare 变量名 cursor ... -- 创建一个游标变量
close 变量名; -- 关闭游标
create procedure test()
    begin
        declare stopflag int default 0;
        declare username VARCHAR(32);
        declare username_cur cursor for select name from users where id%2=0;
        -- 游标变量username_cur保存了查询的临时结果,即结果集
        -- 在游标变量中数据的结尾,将变量stopflag设置为1,用于循环中判断是否结束
        declare continue handler for not found set stopflag=1;
 
        open username_cur; -- 打卡游标
        fetch username_cur into username; -- 游标向前走一步,取出一条记录放到变量username中
        while(stopflag=0) do -- 如果游标还没有结尾,就继续
            begin 
                -- 在用户名前门拼接 '_cur' 字符串
                update users set name=CONCAT(username,'_cur') where name=username;
                fetch username_cur into username;-- 游标向前走一步,取出一条记录放到变量username中
            end;
        end while; -- 结束循环
        close username_cur; -- 关闭游标
    end;

七、自定义函数

-- 创建函数
create function 函数名(参数) returns 返回类型;
-- 函数体
begin ...... end;
-- 指定函数的返回值
returns
--函数调用
select 函数名()。
create function getusername(userid int) returns varchar(32)
    reads sql data  -- 从数据库中读取数据,但不修改数据
    begin
        declare username varchar(32) default '';
        select name into username from users where id=userid;
        return username;
    end;

八、触发器

触发器也是一种数据库对象,在满足定义条件时触发,并执行触发器中定义的语句集合。

创建触发器create trigger 触发器名
after、before:在对表操作之前(before)或者之后(after)触发动作。
操作事件:insert,update,delete等修改操作
影响的范围:for each row

1、需求:出于审计目的,当有人往表users插入一条记录时,把插入的userid,username,插入动作和操作时间记录下来。

create trigger tr_users_insert after insert on users
    for each row 
    begin 
        insert into oplog(userid,username,action,optime)
        values(NEW.userid,NEW.name,'insert',now());
    end;

2、需求:出于审计目的,当删除users表时,记录删除前该记录的主要字段值

create trigger tr_users_delete before delete on users
    for each row 
    begin 
        insert into oplog(userid,username,action,optime)
        values(OLD.id,OLD.name,'delete',now());
    end;

九、事件

触发器只是针对某个表产生的事件执行一些语句,而事件调度器则是在某一个(间隔)时间执行一些语句。

在使用这个功能之前必须确保事件调度器event_scheduler已开启:

SET GLOBAL event_scheduler = 1;
-- 或者
SET GLOBAL event_scheduler = on;

--查看开启情况
show variables like '%event_scheduler%';
create event[IF NOT EXISTS]event_name -- 创建使用create event
    ON SCHEDULE schedule -- on schedule 什么时候来执行
    [ON COMPLETION [NOT] PRESERVE] -- 调度计划执行完成后是否还保留
    [ENABLE | DISABLE] -- 是否开启事件,默认开启
    [COMMENT 'comment'] -- 事件的注释
    DO sql_statement; -- 这个调度计划要做什么?

需求:设计一个福彩的开奖过程,每3分钟开奖一次

-- 存储过程
create procedure test()
        begin 
            insert into lottery(num1,num2,num3,ctime)
            select FLOOR(rand()*9)+1,FLOOR(rand()*9)+1,FLOOR(rand()*9)+1,now();
        end;
-- 事件
create event if not exists test_event -- 创建一个事件
        on schedule every  3 minute -- on schedule 每三分钟执行一次
        on completion preserve 
        do call test;  --调用存储过程

参考文章:mysql存储过程学习笔记

到此这篇关于Mysql存储过程、触发器、事件调度器使用入门的文章就介绍到这了,更多相关Mysql存储过程、触发器、事件调度器内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
详解MySQL主从复制及读写分离
May 07 MySQL
MySQL 可扩展设计的基本原则
May 14 MySQL
MySql 8.0及对应驱动包匹配的注意点说明
Jun 23 MySQL
SQL实现LeetCode(178.分数排行)
Aug 04 MySQL
MySQL连接控制插件介绍
Sep 25 MySQL
MySQL笔记 —SQL运算符
Jan 18 MySQL
浅谈如何保证Mysql主从一致
Mar 13 MySQL
关于MySQL临时表为什么可以重名的问题
Mar 22 MySQL
深入理解MySQL中MVCC与BufferPool缓存机制
May 25 MySQL
MySQL数据库安装方法与图形化管理工具介绍
May 30 MySQL
MySQL数据库实验之 触发器和存储过程
Jun 21 MySQL
MySQL下载安装配置详细教程 附下载资源
Sep 23 MySQL
MySQL数据库⾼可⽤HA实现小结
weblogic服务建立数据源连接测试更新mysql驱动包的问题及解决方法
Jan 22 #MySQL
解决Mysql多行子查询的使用及空值问题
Jan 22 #MySQL
如何避免mysql启动时错误及sock文件作用分析
Jan 22 #MySQL
教你使用VS Code的MySQL扩展管理数据库的方法
Jan 22 #MySQL
彻底解决MySQL使用中文乱码的方法
Jan 22 #MySQL
mysql分组后合并显示一个字段的多条数据方式
Jan 22 #MySQL
You might like
关于ThinkPHP中的异常处理详解
2018/05/11 PHP
PHP实现的AES 128位加密算法示例
2019/09/16 PHP
基于jQuery实现的百度导航li拖放排列效果,即时更新数据库
2012/07/31 Javascript
js倒计时小程序
2013/11/05 Javascript
JavaScript验证图片类型(扩展名)的函数分享
2014/05/05 Javascript
jQuery获取节点和子节点文本的方法
2014/07/22 Javascript
extjs 如何给column 加上提示
2014/07/29 Javascript
JavaScript中Number.NEGATIVE_INFINITY值的使用详解
2015/06/05 Javascript
深入浅析JavaScript中数据共享和数据传递
2016/04/25 Javascript
Bootstrap3多级下拉菜单
2017/02/24 Javascript
JavaScript组件开发之输入框加候选框
2017/03/10 Javascript
bootstrap-table实现服务器分页的示例 (spring 后台)
2017/09/01 Javascript
浅谈Vue.js中的v-on(事件处理)
2017/09/05 Javascript
Js利用console计算代码运行时间的方法示例
2017/09/24 Javascript
angularjs实现柱状图动态加载的示例
2017/12/11 Javascript
Material(包括Material Icon)在Angular2中的使用详解
2018/02/11 Javascript
详解JS函数防抖
2020/06/05 Javascript
vue中echarts图表大小适应窗口大小且不需要刷新案例
2020/07/19 Javascript
requests和lxml实现爬虫的方法
2017/06/11 Python
在Python程序员面试中被问的最多的10道题
2017/12/05 Python
终端命令查看TensorFlow版本号及路径的方法
2018/06/13 Python
对Python3中bytes和HexStr之间的转换详解
2018/12/04 Python
详解Python 切片语法
2019/06/10 Python
Python自动化完成tb喵币任务的操作方法
2019/10/30 Python
基于Pytorch SSD模型分析
2020/02/18 Python
pandas的resample重采样的使用
2020/04/24 Python
pandas按照列的值排序(某一列或者多列)
2020/12/13 Python
美国领先的个性化礼品商城:Personalization Mall
2019/07/27 全球购物
小米乌克兰网上商店:Xiaomi.UA
2019/10/29 全球购物
远程调用的原理
2014/07/05 面试题
优秀村官事迹材料
2014/01/10 职场文书
敬老院标语
2014/06/27 职场文书
学校党的群众路线教育实践活动总结报告
2014/07/03 职场文书
学生实习证明模板汇总
2014/09/25 职场文书
2014年转正工作总结
2014/11/08 职场文书
Win11无法访问设备和打印机 如何解决页面空白
2022/04/09 数码科技