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 26 MySQL
MySQL Router实现MySQL的读写分离的方法
May 27 MySQL
MySQL中in和exists区别详解
Jun 03 MySQL
MySQL 外键约束和表关系相关总结
Jun 20 MySQL
详解MySQL多版本并发控制机制(MVCC)源码
Jun 23 MySQL
mysql定时自动备份数据库的方法步骤
Jul 07 MySQL
SQL之各种join小结详细讲解
Aug 04 MySQL
MySQL Server层四个日志的实现
Mar 31 MySQL
MySQL表锁、行锁、排它锁及共享锁的使用详解
Apr 02 MySQL
排查MySQL生产环境索引没有效果
Apr 11 MySQL
mysql使用 not int 子查询隐含陷阱
Apr 12 MySQL
MYSQL如何查看操作日志详解
May 30 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中用header图片地址 简单隐藏图片源地址
2008/04/09 PHP
《PHP编程最快明白》第七讲:php图片验证码与缩略图
2010/11/01 PHP
php设置编码格式的方法
2013/03/05 PHP
php生成shtml类用法实例
2014/12/09 PHP
弹出广告特效代码(一个IP只弹出一次)
2007/05/11 Javascript
jQuery Select(单选) 模拟插件 V1.3.62 改进版
2010/07/17 Javascript
jQuery Ajax方法调用 Asp.Net WebService 的详细实例代码
2011/04/27 Javascript
Javascript实现动态菜单添加的实例代码
2013/07/05 Javascript
js 控制页面跳转的5种方法
2013/09/09 Javascript
js图片翻书效果代码分享
2015/08/20 Javascript
Centos7 中 Node.js安装简单方法
2016/11/02 Javascript
AngularJS辅助库browserTrigger用法示例
2016/11/03 Javascript
jQuery弹出层插件popShow用法示例
2017/01/23 Javascript
JS在浏览器中解析Base64编码图像
2017/02/09 Javascript
jquery实现页面加载效果
2017/02/21 Javascript
jsonp跨域请求实现示例
2017/03/13 Javascript
详解React开发中使用require.ensure()按需加载ES6组件
2017/05/12 Javascript
Bootstrap Table使用整理(三)
2017/06/09 Javascript
javascript实现非常简单的小数取整功能示例
2017/06/13 Javascript
Vue.js单向绑定和双向绑定实例分析
2018/08/14 Javascript
微信小程序实现带缩略图轮播效果
2018/11/04 Javascript
electron中使用bootstrap的示例代码
2018/11/06 Javascript
实用的Vue开发技巧
2019/05/30 Javascript
微信小程序自定义tabbar custom-tab-bar 6s出不来解决方案(cover-view不兼容)
2019/11/01 Javascript
Django中在xadmin中集成DjangoUeditor过程详解
2019/07/24 Python
全球速卖通法国在线交易平台:AliExpress法国
2017/07/07 全球购物
英国家庭珠宝商:T. H. Baker
2018/02/08 全球购物
Foot Locker加拿大官网:美国知名运动产品零售商
2019/07/21 全球购物
班会关于环保演讲稿
2013/12/29 职场文书
小学语文课后反思精选
2014/04/25 职场文书
学校三节实施方案
2014/06/09 职场文书
妈妈活动方案
2014/08/15 职场文书
网上祭先烈心得体会
2014/09/01 职场文书
投标承诺函范文
2015/01/21 职场文书
MySQL 表空间碎片的概念及相关问题解决
2021/05/07 MySQL
疑《守望先锋2》A测截图泄露 或将推出新模式、新界面
2022/04/03 其他游戏