MySQL触发器 - AFTER INSERT触发器+ UDF sys_exec()问题

时间:2010-09-06 13:46:13

标签: mysql insert triggers user-defined-functions

问题:我有一张包含某些记录的表格。插入完成后,我想通过MySQL的sys_ * UDF调用外部程序(php脚本)。 现在,问题 - 我已经将记录的ID传递给脚本的触发器。 当我尝试通过脚本提取数据时,我得到0行。 在我自己的测试中,我得出结论,触发器调用php脚本并在实际插入发生之前传递参数,因此我没有得到给定ID的记录。 我在MySQL 5.0.75和5.1.41(Ubuntu OS)上测试了这个。 我可以确认参数在实际插入发生之前传递给脚本,因为我添加了sleep(2);到我的PHP脚本,我已正确获取数据。 没有睡觉();声明,我收到了给定身份证的0条记录。

我的问题是 - 如何解决这个问题,而不必在PHP脚本中硬编码某种延迟? 我没有自由假设2秒(或10秒)将是足够的延迟,所以我希望一切都“自然地”流动,当一个命令完成时 - 另一个命令执行。

我假设如果触发器是AFTER INSERT类型,则在MySQL实际插入数据后,触发器体内的所有内容都将被执行。

表格布局:

CREATE TABLE test (
id int not null auto_increment PRIMARY KEY,
random_data varchar(255) not null
);

触发器布局:

DELIMITER $$

CREATE TRIGGER `test_after_insert` AFTER INSERT ON `test` 
FOR EACH ROW BEGIN

SET @exec_var = sys_exec(CONCAT('php /var/www/xyz/servers/dispatcher.php ', NEW.id));
END;
$$

DELIMITER ;

免责声明:我知道使用sys_exec函数时的安全问题,我的问题是MySQL没有插入FIRST,然后用必要的参数调用脚本。 如果有人能够解释如何解决这个问题,或者有一种不同的方法,不涉及SELECT INTO OUTFILE和使用FAM - 我将非常感激。提前谢谢。

2 个答案:

答案 0 :(得分:4)

即使您使用AFTER触发器,该行也尚未提交。但是sys_exec()在php脚本退出之前不会返回,因此AFTER触发器无法完成,因此您也无法提交INSERT。

这是设计的。毕竟,您可以在同一事务中执行更多操作,或者您可以回滚事务。这是从触发器调用外部进程的问题:外部进程无法在数据库中查看事务范围内的数据。

您不应该使用触发器执行此任务。最好,您应该使用触发器设置“标志”列,然后编写外部进程以查找设置了标志的行,然后调用该PHP脚本。这样,只会处理已成功插入并提交的行。

答案 1 :(得分:3)

如果我清楚地理解,你在数据库中插入一行。这会调用一个触发器来启动用PHP编写的外部命令。该命令通过使用插入行的 id 来查询相同的数据库?

我不认为这是“延迟”的问题。

真正的“问题”是你的初始插入,你的外部命令连接到两个不同的sessions上的同一个数据库 - 可能是两个不同的transactions(取决于你的数据库引擎和事务隔离级别) )。

假设,当调用行插入的触发器尚未提交给DB时。因此外部命令仍然可以看到之前的数据库。


顺便说一句,如果上面的解释是相当推测的 - 对我来说更明显的是你应该考虑一种不同的设计,而不是试图让它按原样工作。