在 MySQL 中创建预定事件
Creating a scheduled event in MySQL
我在名为 fouras 的 MySQL 数据库中提供了 table 个名称:
mysql> desc offer;
+------------------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+---------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| description | varchar(5000) | NO | | NULL | |
| end_date | date | NO | | NULL | |
| is_accepted | bit(1) | NO | | NULL | |
| is_active | bit(1) | NO | | NULL | |
| is_draft | bit(1) | NO | | NULL | |
| is_processed | bit(1) | NO | | NULL | |
| is_removed | bit(1) | NO | | NULL | |
| max_reservation_number | int(11) | NO | | NULL | |
| promotion_first_param | varchar(255) | YES | | NULL | |
| promotion_product | varchar(255) | YES | | NULL | |
| promotion_second_param | varchar(255) | YES | | NULL | |
| promotion_type | varchar(255) | NO | | NULL | |
| publish_date | date | YES | | NULL | |
| remove_time_stamp | bigint(20) | YES | | NULL | |
| start_date | date | NO | | NULL | |
| title | varchar(255) | NO | | NULL | |
| views_number | int(11) | YES | | NULL | |
| local_business | bigint(20) | YES | MUL | NULL | |
+------------------------+---------------+------+-----+---------+----------------+
19 rows in set (0.00 sec)
现在,我想定期检查报价是否已过期(end_date > 今天),为此我正在尝试使用 MySQL 预定事件:
CREATE EVENT IF NOT EXISTS check_expired_offers
ON SCHEDULE EVERY 10 MINUTE
DO
BEGIN
DECLARE id INT;
DECLARE end_date DATE;
DECLARE offer_cursor CURSOR FOR SELECT id, end_date FROM fouras.offer;
OPEN offer_sursor;
offer_loop: LOOP
FETCH offer_cursor into id, end_date;
IF end_date < NOW() THEN
UPDATE fouras.offer set is_active = false;
END IF;
END LOOP
END;
但是 MySQL 在我尝试添加此事件时抛出错误:
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 5 0,127 sec
错误是关于分隔符的,这个tutorial对我帮助很大
============================
发现分隔符问题。
============================
这是修改后的 event
:
DELIMITER $$
CREATE EVENT IF NOT EXISTS check_expired_offers
ON SCHEDULE EVERY 10 MINUTE
DO
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE id INT;
DECLARE end_date DATE;
DECLARE offer_cursor CURSOR FOR SELECT id, end_date FROM fouras.offer;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
OPEN offer_cursor;
offer_loop:
LOOP
FETCH offer_cursor into id, end_date;
IF finished = 1 THEN
LEAVE offer_loop;
END IF;
IF end_date < NOW() THEN
UPDATE fouras.offer set is_active = false;
END IF;
END LOOP ;
END $$
DELIMITER ;
Learn delimiters in MySQL
注意: 我也在那里使用了一个名为 finished
.
的变量
其中finished是一个变量,表示游标已经到达结果集的末尾。请注意,处理程序声明必须出现在存储程序中的变量和游标声明之后。
下图说明了 MySQL 游标的工作原理。
我在名为 fouras 的 MySQL 数据库中提供了 table 个名称:
mysql> desc offer;
+------------------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+---------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| description | varchar(5000) | NO | | NULL | |
| end_date | date | NO | | NULL | |
| is_accepted | bit(1) | NO | | NULL | |
| is_active | bit(1) | NO | | NULL | |
| is_draft | bit(1) | NO | | NULL | |
| is_processed | bit(1) | NO | | NULL | |
| is_removed | bit(1) | NO | | NULL | |
| max_reservation_number | int(11) | NO | | NULL | |
| promotion_first_param | varchar(255) | YES | | NULL | |
| promotion_product | varchar(255) | YES | | NULL | |
| promotion_second_param | varchar(255) | YES | | NULL | |
| promotion_type | varchar(255) | NO | | NULL | |
| publish_date | date | YES | | NULL | |
| remove_time_stamp | bigint(20) | YES | | NULL | |
| start_date | date | NO | | NULL | |
| title | varchar(255) | NO | | NULL | |
| views_number | int(11) | YES | | NULL | |
| local_business | bigint(20) | YES | MUL | NULL | |
+------------------------+---------------+------+-----+---------+----------------+
19 rows in set (0.00 sec)
现在,我想定期检查报价是否已过期(end_date > 今天),为此我正在尝试使用 MySQL 预定事件:
CREATE EVENT IF NOT EXISTS check_expired_offers
ON SCHEDULE EVERY 10 MINUTE
DO
BEGIN
DECLARE id INT;
DECLARE end_date DATE;
DECLARE offer_cursor CURSOR FOR SELECT id, end_date FROM fouras.offer;
OPEN offer_sursor;
offer_loop: LOOP
FETCH offer_cursor into id, end_date;
IF end_date < NOW() THEN
UPDATE fouras.offer set is_active = false;
END IF;
END LOOP
END;
但是 MySQL 在我尝试添加此事件时抛出错误:
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 5 0,127 sec
错误是关于分隔符的,这个tutorial对我帮助很大
============================
发现分隔符问题。
============================
这是修改后的 event
:
DELIMITER $$
CREATE EVENT IF NOT EXISTS check_expired_offers
ON SCHEDULE EVERY 10 MINUTE
DO
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE id INT;
DECLARE end_date DATE;
DECLARE offer_cursor CURSOR FOR SELECT id, end_date FROM fouras.offer;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
OPEN offer_cursor;
offer_loop:
LOOP
FETCH offer_cursor into id, end_date;
IF finished = 1 THEN
LEAVE offer_loop;
END IF;
IF end_date < NOW() THEN
UPDATE fouras.offer set is_active = false;
END IF;
END LOOP ;
END $$
DELIMITER ;
Learn delimiters in MySQL
注意: 我也在那里使用了一个名为 finished
.
其中finished是一个变量,表示游标已经到达结果集的末尾。请注意,处理程序声明必须出现在存储程序中的变量和游标声明之后。
下图说明了 MySQL 游标的工作原理。