mysql数据库存储过程和定时器

来源:互联网 发布:宁波数据分析招聘 编辑:程序博客网 时间:2024/06/01 15:56

一、mysql数据库存储过程有过编程经验的人应该都很熟悉,先来说一下它的优点。

  1. 可以更快的执行,如果项目需要大量的sql语句或者重复执行的话,这时候存储过程的优点就会提现出来,它可以比程序执行的更快,性能更高
  2. 它还支持模式化设计,也就是说只需创建一次,就可以在定时器中重复调用无数次,而且还减少了开发人员的工作量
  3. 安全性高,可设定只有某此用户才具有对指定存储过程的使用权
  4. 可以封装数据逻辑和业务规则,以便用户可以仅通过开发人员和数据库管理员打算使用的方式访问数据和对象
  5. 可以禁止查询和修改数据,这样将阻止用户恶意或无意中损坏数据或执行查询,以避免降低服务器或网络的性能。

二、来吧,上重点,存储过程,这可是宝宝用了洪荒之力写出来的,以前没写过,第一次写

BEGIN        DECLARE done INT DEFAULT 0;        DECLARE tid INT(11) DEFAULT NULL;        DECLARE tmoney VARCHAR(50) DEFAULT null;        DECLARE totalMoney VARCHAR(50) DEFAULT null;        DECLARE cur CURSOR FOR select id from productitem_info where endTime<=curdate() and state=1;        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;        OPEN cur;                REPEAT                    FETCH cur INTO tid;                    IF NOT done THEN                        select zje INTO tmoney from v_productzcs where productId=tid;                            if tmoney is null then                                 set tmoney=0;                        end IF;                        SELECT collectMoney into totalMoney from productitem_info where id=tid;                        IF tmoney>=totalMoney THEN                             UPDATE productitem_info set state=3 where id=tid;                        ELSE                            SET done=0;                        END IF;                    END IF;                UNTIL done END REPEAT;        CLOSE cur;        COMMIT;END

注:先说一下我写这段过程的意思,就是为了修改productitem_info 中的state=3这个状态,然后得符合endTime<=curdate() and state=1;这些条件,还得让tmoney>=totalMoney的时候,才可以修改state状态。然后在简单说下里边代码的意思,DECLARE 就是定义变量的意思,我理解的就是相当于Java里边的int;DECLARE 游标名CURSOR FOR 查询语句,这句就是声明游标,这个游标名得是唯一的;open打开先前声明的游标;REPEAT….UNTIL done END REPEAT;我理解的就是Java里边的for循环,也可以用while循环;FETCH 游标名 INTO 变量[, 变量2] …这句用指定的打开游标读取下一行(如果有下一行的话),并且前进游标指针;close关闭游标;commit提交这些数据

三、定时器
定时器我就是在数据库中创建了个事件,然后定期执行上面的存储过程就OK了。

  1. 你得先查下这个事件的状态,是否开启
SHOW VARIABLES LIKE 'event_scheduler'
如果是off(未开启),那就得执行第二步,on(已开启)就不用第二步2. 在mysql程序的目录下找到my.ini文件,添加一个项 event_scheduler = 1,保存后重启mysql服务即可,重启服务可以在服务管理里面找到;或者脚本来实现,开启event_scheduler sql指令
SET GLOBAL event_scheduler = ON;SET @@global.event_scheduler = ON;SET GLOBAL event_scheduler = 1;SET @@global.event_scheduler = 1;
 3. 第三步很重要,一定要记住,是在查询里面运行下面代码,并不是在事件中,一定要记清楚,我可是用了洪荒之力才发现是这种弱智错误的,希望大家别走我的弯路
set global event_scheduler=1; CREATE EVENT IF NOT EXISTS auto_productInfo_state   ON SCHEDULE EVERY 1 SECONDON COMPLETION PRESERVE  DO CALL product_info_state();SELECT * FROM information_schema.events;ALTER EVENT auto_productInfo_state ON  COMPLETION PRESERVE ENABLE; 

注:这是每秒钟执行一次

CREATE EVENT IF NOT EXISTS auto_productInfo_state  ON SCHEDULE EVERY 1 day STARTS  date_add(concat(current_date(), ' 00:00:00'), interval 0 second)  ON COMPLETION PRESERVE ENABLE    DO CALL product_info_state()

注:这是每天晚上0点执行

4. 开始时间任务
alter event auto_productInfo_state  ON COMPLETION PRESERVE ENABLE;  
关闭时间任务
alter event auto_productInfo_state  ON COMPLETION PRESERVE DISABLE;  

到这里就大功告成了,但是我得把我之前那个错误和解决办法贴出来,因为当时我搜了老半天,网上只有人问这个问题,但是没人解答,当时心都碎了,所以我一定要把这个错误贴出来

这里写图片描述

对,就是这个错误!搞了我头都大了,幸亏我是个积极乐观的向上好青年,要不然非得得抑郁症不可,解决办法其实挺逗逼的。
解决办法就是上面说的,不要让代码在事件中执行,新建查询,在查询里面执行,事件中只写名称,然后写上你想定期执行哪个表或者是存储过程即可

CALL product_info_state()

如果大家有什么好的意见或者建议,欢迎大家给我留言,谢谢大家

1 0