mysql – 从触发器调用的存储过程中的动态语句的解决方法
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了mysql – 从触发器调用的存储过程中的动态语句的解决方法,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2098字,纯文字阅读大概需要3分钟。
内容图文
![mysql – 从触发器调用的存储过程中的动态语句的解决方法](/upload/InfoBanner/zyjiaocheng/902/ba13e8406b0749759c59e928f8dd5354.jpg)
Mysql PREPARE和EXECUTE语句不能在触发器调用的存储过程中使用.结果将是错误代码:1336.存储函数或触发器中不允许动态SQL.
有谁知道这方面的合理工作?
解决方法:
您无法从TRIGGER内部运行PREPARE / EXECUTE,但您可以从EVENT运行(如果您运行的是MySQL 5.5或更高版本).
以下是从EVENT运行PREPARE / EXECUTE的示例:
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;
然后运行这个:
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;
将产生此输出:
+-------------+------+
| i | v |
+-------------+------+
| -1348550619 | ex 1 |
| -1348550621 | ex 2 |
+-------------+------+
2 rows in set (0.00 sec)
如果您不想使用EVENT,或者等待第二个左右触发它,您可以在每个可能导致触发TRIGGER的命令之后添加一个CALL proc().
内容总结
以上是互联网集市为您收集整理的mysql – 从触发器调用的存储过程中的动态语句的解决方法全部内容,希望文章能够帮你解决mysql – 从触发器调用的存储过程中的动态语句的解决方法所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。