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 角色(role)功能介绍
Apr 24 MySQL
浅谈mysql增加索引不生效的几种情况
Jun 23 MySQL
MySQL非空约束(not null)案例讲解
Aug 23 MySQL
MySQL去除重叠时间求时间差和的实现
Aug 23 MySQL
关于MySQL中的 like操作符详情
Nov 17 MySQL
MySQL分区路径子分区再分区
Apr 13 MySQL
Mysql调整优化之四种分区方式以及组合分区
Apr 13 MySQL
MySQL 表锁定 LOCK和UNLOCK TABLES的 SQL语法
Apr 18 MySQL
mysql 获取相邻数据项
May 11 MySQL
MYSQL如何查看操作日志详解
May 30 MySQL
SQLServer常见数学函数梳理总结
Aug 05 MySQL
MySQL存储过程及语法详解
Aug 05 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
浅析php单例模式
2014/11/25 PHP
phpMyAdmin通过密码漏洞留后门文件
2018/11/20 PHP
阻止JavaScript事件冒泡传递(cancelBubble 、stopPropagation)
2007/05/08 Javascript
javascript中直接写php代码的方法
2013/07/31 Javascript
js 距离某一时间点时间是多少实现代码
2013/10/14 Javascript
js给selected添加options的方法
2015/05/06 Javascript
详解JavaScript的策略模式编程
2015/06/24 Javascript
jquery+CSS3实现淘宝移动网页菜单效果
2015/08/31 Javascript
Active控件问题小结(附解决办法)
2016/06/09 Javascript
JavaScript中Form表单技术汇总(推荐)
2016/06/26 Javascript
jQuery中Nicescroll滚动条插件的用法
2016/11/10 Javascript
Vue 单文件中的数据传递示例
2017/03/21 Javascript
JavaScript中最常用的10种代码简写技巧总结
2017/06/28 Javascript
利用原生JS实现data方法示例代码
2019/05/28 Javascript
关于layui的下拉搜索框异步加载数据的解决方法
2019/09/28 Javascript
js中的面向对象之对象常见创建方法详解
2019/12/16 Javascript
Websocket 向指定用户发消息的方法
2020/01/09 Javascript
理解JavaScript中的对象
2020/08/25 Javascript
Python单元测试框架unittest简明使用实例
2015/04/13 Python
在Python的web框架中中编写日志列表的教程
2015/04/30 Python
Python中第三方库Requests库的高级用法详解
2017/03/12 Python
Python实现的绘制三维双螺旋线图形功能示例
2018/06/23 Python
详解用Python实现自动化监控远程服务器
2019/05/18 Python
CSS3实现银灰色动画效果的导航菜单代码
2015/09/01 HTML / CSS
使用CSS3的appearance属性改变元素的外观的方法
2015/12/12 HTML / CSS
Woods官网:加拿大最古老、最受尊敬的户外品牌之一
2020/09/12 全球购物
php优化查询foreach代码实例讲解
2021/03/24 PHP
如何做好总经理助理
2013/11/12 职场文书
质量承诺书格式
2014/05/20 职场文书
小学生放飞梦想演讲稿
2014/08/26 职场文书
孩子教育的心得体会
2014/09/01 职场文书
党员群众路线教育实践活动剖析材料
2014/10/10 职场文书
项目转让协议书
2014/10/27 职场文书
精神文明建设汇报材料
2014/12/24 职场文书
与死神共舞观后感
2015/06/15 职场文书
建立共青团委员会的请示
2019/04/02 职场文书