mysql脚本编写--触发器、存储过程、定时任务

最近有个网页需要展示统计数据,需要对系统的数据作统计,所以新生成了几个表格,通过mysql脚本实现数据的自动统计存储。
由于没有找到mysql所有脚本编写的类似说明手册的内容,所以只能每个问题单独搜索然后编写。

一、通过触发器实现数据表有数据插入时,相应更新到统计表格中。

详细的触发器说明请见上一篇文章,这里把我写的贴上来。在每次插入一行之后,更新另一个表的统计数据。

DROP TRIGGER IF EXISTS `update_alert_count`;
delimiter ;;
CREATE TRIGGER `update_alert_count` AFTER INSERT ON `eagle_alert_data` FOR EACH ROW begin
    if((NEW.app_id,NEW.site,DATE(NEW.time)) not in (select DISTINCT app_id,site,DATE(time) from eagle_alert_count_by_app)) then
        insert into eagle_alert_count_by_app(app_id,time,count,site) values(NEW.app_id,DATE(NEW.time),1,NEW.site);  
    else
        UPDATE eagle_alert_count_by_app set count=count+1 where app_id=NEW.app_id and site= NEW.site and DATE(time)=DATE(NEW.time);
    end if;
end
;;
delimiter ;

二、定时任务更新数据表

实现功能为每日1点将一个表中昨日的数据取出来,与系统存储的历史最大表比较,若更大则进行更新。

1、存储过程中读取select数据集并进行循环处理

需要实现一个存储过程,实现的功能为读取某个表中的若干行数据,然后经过判断,插入或更新另外一个表。类似于python里的fetch后的for循环。网上搜索后,用游标实现。(参考:https://bbs.csdn.net/topics/370065921

示例为:

CREATE PROCEDURE curdemo()
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE a CHAR(16);
  DECLARE b,c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

  OPEN cur1;
  OPEN cur2;

  REPEAT
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF NOT done THEN
       IF b < c THEN
          INSERT INTO test.t3 VALUES (a,b);
       ELSE
          INSERT INTO test.t3 VALUES (a,c);
       END IF;
    END IF;
  UNTIL done END REPEAT;

  CLOSE cur1;
  CLOSE cur2;
END

个人理解,done是用来定义是否读取完全部数据的标志位。FETCH即读取一行数据出来赋给相应的值,REPEAT为循环。

2、存储过程代码

DELIMITER //
DROP PROCEDURE IF EXISTS alert_count_max_compare//
CREATE PROCEDURE alert_count_max_compare() 
BEGIN
    DECLARE done INT DEFAULT 0;#这里可以定义变量
    DECLARE m_app_id VARCHAR(50);
    DECLARE m_site VARCHAR(20);
    DECLARE m_count INT;
    DECLARE m_time datetime(6);
    DECLARE cur1 CURSOR FOR SELECT app_id,site,count,time FROM eagle_alert_count_by_app WHERE CURDATE()-DATE(time) =1 order by app_id;#相当于读取一个表的内容的数据集赋给游标
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    OPEN cur1;

    REPEAT
        FETCH cur1 INTO m_app_id,m_site,m_count,m_time;#每个循环内游标都读取数据集内的一条内容
        IF NOT done THEN #相当于游标读取内容,直至读完为止
            if((m_app_id,m_site) not in (select DISTINCT app_id,site from eagle_alert_count_max)) then #if后面如果只是一行代码,使用then,如果多行代码要用beginend包起来(这里多行代码包起来试了好像失败了,具体的不太清楚)
                insert into eagle_alert_count_max(app_id,site,max_count,time) values(m_app_id,m_site,m_count,DATE(m_time)); 
            ELSE
                SELECT max_count INTO @count_data FROM eagle_alert_count_max WHERE app_id=m_app_id and site=m_site; #可以用INTO @count_data赋值给变量后续使用,但是没有确定如果select出来多个值会怎么样,这里结果是唯一一行
                if m_count>@count_data then
                    UPDATE eagle_alert_count_max set max_count=m_count,time=DATE(m_time) where app_id=m_app_id and site=m_site;
                end if; #所有的if后面都要带end if
            end if;
        END IF;
    UNTIL done END REPEAT;

    CLOSE cur1;

END//

在information_schema.Routines表中查看存储过程是否定义成功,可以使用CALL alert_count_max_compare();来测试存储过程是否正确。

3、编写定时任务

定义一个事件来执行定时任务(参考:https://www.cnblogs.com/laowu-blog/p/5073665.htmlhttps://www.cnblogs.com/it-aaron/p/6756924.htmlhttps://www.cnblogs.com/ctaixw/p/5660531.html

DROP EVENT IF EXISTS alert_count_max_compare_job;
delimiter $$
CREATE EVENT alert_count_max_compare_job
ON SCHEDULE EVERY 1 day STARTS TIMESTAMP '2018-08-14 01:00:00' #这里的1 day可以替换成别的时间间隔,'2018-08-14 01:00:00'表示从这个时间开始
ON COMPLETION PRESERVE #该设置当event到期了,event会被disable,但是该event还是会存在
DO
BEGIN
CALL alert_count_max_compare(); #调用存储过程
end  $$
delimiter ;

4、定时任务的开启

查看event是否开启 : SHOW VARIABLES LIKE ‘%event_sche%’;
将事件计划开启 : SET GLOBAL event_scheduler = 1;
开启事件任务 : ALTER EVENT eventName ON COMPLETION PRESERVE ENABLE;
查看事件任务 : SHOW EVENTS ;

如果需要关闭,使用如下命令:

将事件计划关闭 : SET GLOBAL event_scheduler = 0;
关闭事件任务 : ALTER EVENT eventName ON COMPLETION PRESERVE DISABLE;

其他编写脚本时的内容
1、mysql设置唯一约束
ALTER TABLE eagle_alert_count_max ADD UNIQUE KEY(app_id,site);
这个是两个列联合唯一,如果只是一个列唯一,将括号内的字段改成一个就可以了。

其他参考内容:
sql语句的用法及函数使用手册参考如下:
http://www.w3school.com.cn/sql/sql_syntax.asp

存储过程的编写说明:
1、mysql存储过程 变量和参数类型,https://blog.csdn.net/jxpxlinkui/article/details/79709037
存储过程变量具有数据类型和长度,与mysql的SQL数据类型一致,因此甚至可以指定默认值、字符集 和排序规则。

2、MySQL——查看存储过程和函数,https://blog.csdn.net/qq_41573234/article/details/80411079
在information_schema.Routines表中查看存储过程

猜你喜欢

转载自blog.csdn.net/xiaokui9/article/details/81699925
今日推荐