我有一个insert触发器,它从表A的行中获取一组列值,并将其中一些插入到表B中,剩下的在表C中。我需要这个操作是一个事务,如果在将数据插入到表B而不是C时出现错误,则应该回滚整个插入操作。
我研究了手册,在this页面的最后,它说触发器中不允许事务
有没有办法在mysql中实现我想要的。
发布于 2012-07-31 08:36:51
是的,你可以,但是你怎么做取决于你的版本。
首先,触发器本身是事务性的;在您的情况下,您有一个insert触发器来执行两次进一步的插入。如果其中一个失败了,你会得到你想要的效果。
考虑以下示例:
CREATE TABLE a (colA INT);
CREATE TABLE b (colB INT);
CREATE TABLE c (colC INT);
delimiter :
CREATE TRIGGER testtrig BEFORE INSERT ON a
FOR EACH ROW BEGIN
INSERT INTO b(colB) VALUES(NEW.colA);
INSERT INTO c(banana) VALUES (NEW.colA); -- note the faulty column name
END;:
delimiter ;
现在,当我运行一个insert失败时,就会发生这种情况:
mysql> INSERT INTO a VALUES (5);
ERROR 1054 (42S22): Unknown column 'banana' in 'field list'
mysql> SELECT * FROM a;
Empty set (0.00 sec)
这与您期望的结果相匹配。
更一般地,如果在尝试插入之前有可用于验证数据的逻辑,则可以通过不同的方式使触发器失败:
我猜您使用的是问题中链接中的5.0,因此如果需要,您可以执行故意的错误,例如故意插入到无效的列中,从而使触发器失败。但是,您在问题中描述的情况已经进行了事务处理,正如我在答案开头所描述的那样。
发布于 2015-07-02 20:49:59
默认情况下,您得到了所要求的结果--触发器中的任何错误都会导致语句失败。因此,如果该语句上存在事务,则会将数据回滚到该语句之前。如果没有事务,那么就不需要。
这可能就是为什么在触发器中不允许创建或结束事务的原因。
所以不需要存储过程。实际上,从触发器调用的存储过程在尝试创建事务时可能会导致错误。
但是,在执行导致触发器的操作之前,可以使用存储过程启动事务。
https://stackoverflow.com/questions/9255608
复制相似问题