Bạn không thể chạy PREPARE
/ EXECUTE
từ bên trong TRIGGER
, nhưng bạn có thể từ EVENT
(nếu bạn đang chạy MySQL 5.5 trở lên).
Đây là một ví dụ về việc chạy PREPARE
/ EXECUTE
từ một EVENT
:
DROP TABLE IF EXISTS tbl1;
DROP TABLE IF EXISTS tbl2;
DROP TABLE IF EXISTS cmds;
DROP PROCEDURE IF EXISTS proc;
DROP TRIGGER IF EXISTS trig;
CREATE TABLE tbl1 (i INT, v VARCHAR(255));
CREATE TABLE tbl2 (i INT, v VARCHAR(255));
CREATE TABLE cmds (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
done BOOL NOT NULL DEFAULT FALSE,
cmd TEXT,
PRIMARY KEY (id),
INDEX (done, id)
);
DELIMITER //
CREATE PROCEDURE proc()
NOT DETERMINISTIC
MODIFIES SQL DATA
proc: BEGIN
DECLARE b_not_found BOOL DEFAULT FALSE;
DECLARE i_id INT UNSIGNED;
DECLARE t_cmd TEXT;
DECLARE v_lock_name VARCHAR(255) DEFAULT 'proc_lock';
DECLARE cur CURSOR FOR
SELECT id, cmd FROM cmds WHERE NOT done ORDER BY id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET b_not_found = TRUE;
IF (NOT GET_LOCK(v_lock_name, 0)) THEN
LEAVE proc;
END IF;
OPEN cur;
loop1: LOOP
FETCH cur INTO i_id, t_cmd;
IF b_not_found THEN
LEAVE loop1;
END IF;
SET @cmd = t_cmd;
PREPARE stmt FROM @cmd;
EXECUTE stmt;
DROP PREPARE stmt;
UPDATE cmds SET done = TRUE WHERE id = i_id;
END LOOP;
CLOSE cur;
DO RELEASE_LOCK(v_lock_name);
END;
//
CREATE TRIGGER trig
BEFORE INSERT ON tbl1
FOR EACH ROW
BEGIN
INSERT INTO cmds SET cmd =
CONCAT("INSERT INTO tbl2 SET i = ", -NEW.i, ", v = ", QUOTE(NEW.v));
END;
//
DROP EVENT IF EXISTS evnt //
CREATE EVENT evnt
ON SCHEDULE
EVERY 1 SECOND
DO
BEGIN
CALL proc();
END;
//
DELIMITER ;
SET GLOBAL event_scheduler = 1;
Sau đó chạy cái này:
INSERT INTO tbl1 VALUES (UNIX_TIMESTAMP(), 'ex 1');
DO SLEEP(2);
INSERT INTO tbl1 VALUES (UNIX_TIMESTAMP(), 'ex 2');
DO SLEEP(1);
SELECT * FROM tbl2;
sẽ tạo ra đầu ra này:
+-------------+------+
| i | v |
+-------------+------+
| -1348550619 | ex 1 |
| -1348550621 | ex 2 |
+-------------+------+
2 rows in set (0.00 sec)
Nếu bạn không muốn sử dụng EVENT
hoặc đợi khoảng giây để nó kích hoạt, bạn có thể thêm CALL proc()
sau mỗi lệnh sẽ gây ra TRIGGER
để chữa cháy.