课程 › 第 16 章 › 实验三
第 16 章 · 实验三 · 在第五节之后

事件调度器、AT 与 EVERY

先确认事件调度器已经打开,再把例题 1 到例题 5 做一遍:AT 只执行一次,EVERY 周期执行,STARTS 和 ENDS 限定时间段。

环 境

MySQL 8.0 和 MySQL Workbench,机房电脑已装好。所有语句在 Workbench 的 SQL 编辑区中执行。

执 行

Ctrl+Enter 执行光标所在的一句,Ctrl+Shift+Enter 执行全部。Mac 上把 Ctrl 换成 ⌘。

注 意

输入法切到英文。表名、字段名不加引号,字符串值才用单引号。

本次实验的顺序 后一个实验用到前一个的结果

  1. 实验 3-1事件调度器
  2. 实验 3-2立即执行一次
  3. 实验 3-310 秒后执行
  4. 实验 3-4时刻已经过去
  5. 实验 3-5每 5 秒执行一次
  6. 实验 3-6STARTS 与 ENDS
第一步

数据准备(必做)

重建 teaching 库的五张表和教材中的数据,删除本章实验建立的事件、存储过程和表。

整段复制,全部执行下载 .sql
-- 第 16 章实验数据:教材 teaching 库的五张表和教材中的数据
-- 实验一和实验三使用。整段执行一次即可,想从头再做时重新执行。
CREATE DATABASE IF NOT EXISTS teaching DEFAULT CHARACTER SET utf8mb4;
USE teaching;

-- 删除本章实验建立的事件、存储过程和表,表上的触发器随表一起删除
DROP EVENT IF EXISTS event_name1;
DROP EVENT IF EXISTS event_name2;
DROP EVENT IF EXISTS event_name3;
DROP EVENT IF EXISTS event_name4;
DROP EVENT IF EXISTS name4;
DROP EVENT IF EXISTS event_name5;
DROP EVENT IF EXISTS event_name6;
DROP PROCEDURE IF EXISTS pro_score;
DROP TABLE IF EXISTS update_s_log, tb_one, week_score, t_demo;

-- 删除旧的表。先暂时关闭外键检查,库里有别的表引用它们时也能删除
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS sc, tc, avgsal, classroom, s, c, t;
SET FOREIGN_KEY_CHECKS = 1;

-- 课程表
CREATE TABLE c (
  cno CHAR(4) NOT NULL,
  cn VARCHAR(30) NOT NULL,
  ct INT,
  PRIMARY KEY (cno)
);
-- 学生表
CREATE TABLE s (
  sno CHAR(4) NOT NULL,
  sn VARCHAR(20) NOT NULL,
  sex CHAR(2),
  age INT,
  maj VARCHAR(30),
  dept VARCHAR(30),
  PRIMARY KEY (sno)
);
-- 教师表
CREATE TABLE t (
  tno CHAR(4) NOT NULL,
  tn VARCHAR(20) NOT NULL,
  sex CHAR(2),
  age INT,
  prof VARCHAR(20),
  maj VARCHAR(30),
  dept VARCHAR(30),
  sal DECIMAL(8,2),
  PRIMARY KEY (tno)
);
-- 选课表
CREATE TABLE sc (
  sno CHAR(4) NOT NULL,
  cno CHAR(4) NOT NULL,
  score DECIMAL(5,2),
  PRIMARY KEY (sno, cno),
  FOREIGN KEY (sno) REFERENCES s (sno),
  FOREIGN KEY (cno) REFERENCES c (cno)
);
-- 授课表
CREATE TABLE tc (
  tno CHAR(4) NOT NULL,
  cno CHAR(4) NOT NULL,
  tcdate DATE,
  PRIMARY KEY (tno, cno),
  FOREIGN KEY (tno) REFERENCES t (tno),
  FOREIGN KEY (cno) REFERENCES c (cno)
);

INSERT INTO c VALUES
('c1','Java程序设计',40), ('c2','程序设计基础',48), ('c3','线性代数',48),
('c4','数据结构',64), ('c5','数据库系统',56), ('c6','数据挖掘',32),
('c7','高等数学',60), ('c8','控制理论',32);

INSERT INTO s VALUES
('s1','王彤','女',18,'计算机','信息学院'),
('s2','苏乐','男',20,'信息','信息学院'),
('s3','林欣怡','女',19,'信息','信息学院'),
('s4','陶然','男',19,'自动化','工学院'),
('s5','魏立','男',17,'数学','理学院'),
('s6','何欣荣','女',21,'计算机','信息学院'),
('s7','赵琳琳','女',19,'数学','理学院'),
('s8','李轩','男',18,'自动化','工学院');

INSERT INTO t VALUES
('t1','刘杨','男',38,'教授','计算机','信息学院',3800.00),
('t2','石丽','女',28,'讲师','计算机','信息学院',2800.00),
('t3','顾伟','男',35,'副教授','计算机','信息学院',3200.00),
('t4','赵礼','男',45,'教授','自动化','工学院',4267.90),
('t5','赵希希','女',33,'副教授','数学','理学院',3332.67),
('t6','张刚','男',30,'讲师','计算机','工学院',2600.00);

INSERT INTO sc VALUES
('s1','c1',90.50), ('s1','c2',88.00),
('s2','c4',70.00), ('s2','c5',57.00), ('s2','c6',81.50), ('s2','c7',NULL),
('s3','c1',75.00), ('s3','c2',76.50), ('s3','c4',85.00),
('s4','c1',93.00), ('s4','c2',82.00), ('s4','c6',NULL), ('s4','c7',68.00),
('s5','c2',79.00), ('s5','c7',84.00),
('s7','c3',77.00), ('s7','c5',62.00), ('s7','c7',100.00),
('s8','c2',66.00), ('s8','c3',96.00);

INSERT INTO tc VALUES
('t1','c1','2021-09-03'), ('t1','c2','2021-09-04'),
('t2','c5','2021-03-06'), ('t2','c6','2021-09-06'),
('t3','c2','2021-03-08'), ('t3','c4','2021-09-08'),
('t4','c3','2021-03-10'),
('t5','c7','2021-09-12'), ('t5','c8','2021-03-15');
3-1

事件调度器

讲义 · 事件与事件调度器
目的
查看事件调度器是否打开,打开它,再在线程列表中找到它。
前提
已执行数据准备,用 root 连接。
  1. 查看 event_scheduler 的值
  2. 用 SET GLOBAL 打开事件调度器
  3. 查看线程列表

参考答案

可以直接复制到 Workbench 执行
SHOW VARIABLES LIKE 'event_scheduler';
SET GLOBAL event_scheduler = ON;
SHOW PROCESSLIST;

语句解释

event_schedulerMySQL 8.0 默认为 ON
SET GLOBAL修改全局变量,要有管理员权限。重启服务后恢复为配置文件中的值
SHOW PROCESSLIST列出当前的连接和线程,User 为 event_scheduler 的一行就是事件调度器
执行后看:event_scheduler 为 ON。线程列表中有一行 User 为 event_scheduler,State 为 Waiting on empty queue。
3-2

立即执行一次

讲义 · 例题 1:立即建表
目的
完成例题 1:建立立刻执行的事件 event_name1,由它建立表 tb_one。
前提
已完成实验 3-1。
  1. 建立 event_name1,AT NOW(),建表 tb_one
  2. 稍等一下,查看表和事件

参考答案

第 1 步
CREATE EVENT event_name1
ON SCHEDULE AT NOW()
DO CREATE TABLE tb_one (
  tno INT PRIMARY KEY AUTO_INCREMENT,
  ttime TIMESTAMP
);
第 2 步 过两三秒
-- 过 3 秒以后再执行下面的语句
SHOW TABLES;
SHOW EVENTS;

语句解释

AT NOW()在当前时刻执行一次
DO后面是事件要执行的语句
SHOW EVENTS 为空只执行一次的事件执行完就被删除,这是默认的 ON COMPLETION NOT PRESERVE
执行后看:表中多了 tb_one。SHOW EVENTS 没有结果。
3-3

10 秒后执行

讲义 · 例题 2、3:到指定时刻执行
目的
完成例题 2:建立事件 event_name2,10 秒以后向 tb_one 插入一条记录。
前提
已完成实验 3-2。
  1. 建立 event_name2,AT 当前时间加 10 秒
  2. 马上查看事件和 tb_one
  3. 10 秒以后再看

参考答案

第 1 步
CREATE EVENT event_name2
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 10 SECOND
DO INSERT INTO tb_one VALUES (0, NOW());
SHOW EVENTS;
SELECT * FROM tb_one;
第 2 步 过 10 秒以后
-- 过 10 秒以后再执行下面的语句
SELECT * FROM tb_one;
SHOW EVENTS;

语句解释

+ INTERVAL 10 SECOND当前时刻加 10 秒
VALUES (0, NOW())tno 自动增长,写 0 由 MySQL 自动编号
第 1 步SHOW EVENTS 中 Type 为 ONE TIME,tb_one 还是空的
执行后看:第 1 步 tb_one 为空。第 2 步 tb_one 有 1 行,event_name2 已经不在了。
3-4

时刻已经过去

讲义 · 例题 2、3:到指定时刻执行
目的
建立在指定时刻执行一次的事件 event_name3。先写一个已经过去的时刻,看会怎样,再改为明天 8 点执行。
前提
已完成实验 3-3。
  1. 建立 event_name3,时刻用 2021-02-08 16:29:59
  2. 查看提示和事件
  3. 改为明天 8 点,再建一次

参考答案

可以直接复制到 Workbench 执行
CREATE EVENT event_name3
ON SCHEDULE AT '2021-02-08 16:29:59'
DO INSERT INTO tb_one VALUES (0, NOW());
SHOW WARNINGS;
SHOW EVENTS;
CREATE EVENT event_name3
ON SCHEDULE AT CURRENT_DATE + INTERVAL 1 DAY + INTERVAL 8 HOUR
DO INSERT INTO tb_one VALUES (0, NOW());
SHOW EVENTS;

语句解释

提示 1588执行时刻已经过去,事件建立后立即被删除
CURRENT_DATE + INTERVAL 1 DAY明天 0 点,再加 8 小时就是明天 8 点
Execute atSHOW EVENTS 中只执行一次的事件,这一列是执行的时刻
执行后看:第一次建立后提示 1588,SHOW EVENTS 为空。第二次建立后 Execute at 为明天 08:00:00。
3-5

每 5 秒执行一次

讲义 · 例题 4、5:周期执行
目的
完成例题 4:建立周期执行的事件 event_name4,每 5 秒向 tb_one 插入一条记录。
前提
已完成实验 3-4。
  1. 建立 event_name4,EVERY 5 SECOND
  2. 过十几秒查看 tb_one

参考答案

第 1 步
CREATE EVENT event_name4
ON SCHEDULE EVERY 5 SECOND
DO INSERT INTO tb_one VALUES (0, NOW());
第 2 步 过十几秒
-- 过 15 秒以后再执行下面的语句
SELECT * FROM tb_one;
SHOW EVENTS;

语句解释

EVERY 5 SECOND每隔 5 秒执行一次
第一次不写 STARTS 时,建立后立刻执行第一次
一直执行周期事件不会自己停止,实验四再修改和删除它
执行后看:tb_one 中每隔 5 秒多一行,ttime 相差 5 秒。SHOW EVENTS 中 event_name4 的 Type 为 RECURRING。
3-6

STARTS 与 ENDS

讲义 · 例题 4、5:周期执行
目的
仿照例题 5,建立事件 event_name5:从明天开始,在一周之内每 1 小时清空一次 tb_one。
前提
已完成实验 3-5。
  1. 建立 event_name5,EVERY 1 HOUR,加 STARTS 和 ENDS
  2. 查看事件的开始和结束时间

参考答案

可以直接复制到 Workbench 执行
CREATE EVENT event_name5
ON SCHEDULE EVERY 1 HOUR
STARTS CURRENT_DATE + INTERVAL 1 DAY
ENDS CURRENT_DATE + INTERVAL 1 WEEK
DO DELETE FROM tb_one;
SHOW EVENTS;

语句解释

STARTS从什么时刻开始执行
ENDS到什么时刻结束,结束后事件被删除
执行后看:event_name5 的 Starts 为明天 00:00:00,Ends 为 7 天后的 00:00:00。tb_one 暂时不会被清空。
保山学院·人工智能教研室·曹鼎鼎