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锁机制
Apr 05 MySQL
MySQL sql_mode的使用详解
May 08 MySQL
Mysql数据库索引面试题(程序员基础技能)
May 31 MySQL
MySQL Shell import_table数据导入的实现
Aug 07 MySQL
mysql配置SSL证书登录的实现
Sep 04 MySQL
MySQL基于索引的压力测试的实现
Nov 07 MySQL
关于MySQL中的 like操作符详情
Nov 17 MySQL
MySQL优化常用的19种有效方法(推荐!)
Mar 17 MySQL
MySQL事务操作的四大特性以及并发事务问题
Apr 12 MySQL
MySQL数据库事务的四大特性
Apr 20 MySQL
SQL语句中EXISTS的详细用法大全
Jun 25 MySQL
分享很少见很有用的SQL功能CORRESPONDING
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中用数组的方法设置cookies
2011/04/21 PHP
php递归json类实例
2014/12/02 PHP
php输出金字塔的2种实现方法
2014/12/16 PHP
php使用 readfile() 函数设置文件大小大小的方法
2017/08/11 PHP
YII框架实现自定义第三方扩展操作示例
2019/04/26 PHP
NiftyCube——轻松实现圆角边框
2007/02/20 Javascript
javascript Math.random()随机数函数
2009/11/04 Javascript
JS函数验证总结(方便js客户端输入验证)
2010/10/29 Javascript
JavaScript的RequireJS库入门指南
2015/07/01 Javascript
详解JavaScript for循环中发送AJAX请求问题
2020/06/23 Javascript
简单的JS轮播图代码
2016/07/18 Javascript
Vue组件tree实现树形菜单
2017/04/13 Javascript
使用 Vue.js 仿百度搜索框的实例代码
2017/05/09 Javascript
vuex与组件联合使用的方法
2018/05/10 Javascript
基于vue-cli npm run build之后vendor.js文件过大的解决方法
2018/09/27 Javascript
Vue实现点击按钮复制文本内容的例子
2019/11/09 Javascript
uni-app实现获取验证码倒计时功能
2020/11/01 Javascript
Vue中强制组件重新渲染的正确方法
2021/01/03 Vue.js
Python SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)
2014/05/06 Python
Python中几个比较常见的名词解释
2015/07/04 Python
关于Django显示时间你应该知道的一些问题
2017/12/25 Python
Python pandas RFM模型应用实例详解
2019/11/20 Python
如何使用pandas读取txt文件中指定的列(有无标题)
2020/03/05 Python
python实现mean-shift聚类算法
2020/06/10 Python
Keras 切换后端方式(Theano和TensorFlow)
2020/06/19 Python
pytorch 查看cuda 版本方式
2020/06/23 Python
德国电子商城:ComputerUniverse
2017/04/21 全球购物
在加拿大在线租赁和购买电子游戏:Game Access
2019/09/02 全球购物
美国轻奢时尚购物网站:REVOLVE(支持中文)
2020/07/18 全球购物
澳大利亚在线批发商:Simply Wholesale
2021/02/24 全球购物
介绍一下sql server的安全性
2014/08/10 面试题
护士节活动总结
2014/08/29 职场文书
学生逃课检讨书
2015/02/17 职场文书
Python 用户输入和while循环的操作
2021/05/23 Python
攻击最高的10只幽灵系神奇宝贝,坚盾剑怪排第一,第五最为可怕
2022/03/18 日漫
Python如何让字典保持有序排列
2022/04/29 Python