插入触发器后的MySQL - MyISAM与InnoDB

Mik*_*e B 4 mysql triggers myisam innodb

我试图得到一个插入后触发器,以便不回滚对innodb表执行的插入操作.MyISAM似乎没有这个问题.

让我说明一下:

CREATE TABLE `testTable` (
  `id` int(10) AUTO_INCREMENT,
  `data` text,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB; #Engine supports transactions

CREATE TABLE `dummyTable` (
  `id` int(10) AUTO_INCREMENT,
  `data` text,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;


DELIMITER $$
CREATE TRIGGER triggerTest AFTER INSERT ON `testTable`
FOR EACH ROW
BEGIN
  INSERT INTO dummyTable VALUES(1, 2, 3, 4); #This will throw a column count error
END;$$
DELIMITER ;


INSERT INTO testTable(data) VALUES('This insert will be rolled back');
SELECT COUNT(1) FROM testTable; # 0
Run Code Online (Sandbox Code Playgroud)

如果您将引擎更改testTable为MyISAM,原始插入将不会回滚,因为(我假设)MyISAM不支持事务.

CREATE TABLE `testTable` (
  `id` int(10) AUTO_INCREMENT,
  `data` text,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM; #Engine does NOT support transactions

CREATE TABLE `dummyTable` (
  `id` int(10) AUTO_INCREMENT,
  `data` text,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

DELIMITER $$
CREATE TRIGGER triggerTest AFTER INSERT ON `testTable`
FOR EACH ROW
BEGIN
  INSERT INTO dummyTable VALUES(1, 2, 3, 4); #This will throw a column count error
END;$$
DELIMITER ;

INSERT INTO testTable(data) VALUES('This insert will not be rolled back');
SELECT COUNT(1) FROM testTable; # 1
Run Code Online (Sandbox Code Playgroud)

问题:如果触发器中存在错误,是否有一种方法可以在InnoDB表的插入触发器之后保留原始插入?

Ran*_*eed 5

是的,不同的行为与引擎是否支持事务有关:

对于事务表,语句失败应导致回滚语句执行的所有更改.触发器失败会导致语句失败,因此触发器失败也会导致回滚.对于非事务性表,无法执行此类回滚,因此尽管语句失败,但在错误点之前执行的任何更改仍然有效.

你可以声明一个CONTINUE处理程序这个特定的错误:

DELIMITER $$
CREATE TRIGGER triggerTest AFTER INSERT ON `testTable`
FOR EACH ROW
BEGIN
  DECLARE CONTINUE HANDLER
      FOR SQLSTATE '21S01' -- "Column count doesn't match value count"
      BEGIN END; -- do nothing (but continue)
  INSERT INTO dummyTable VALUES(1, 2, 3, 4);
END $$
DELIMITER ;
Run Code Online (Sandbox Code Playgroud)