0

我有一个要在将行插入表之前运行的触发器:

CREATE TABLE IF NOT EXISTS `test`.`t1`(
  `idt1` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `myType` ENUM('A','B','C') NOT NULL DEFAULT 'A',
  PRIMARY KEY (`idt1`) )
ENGINE = InnoDB;

delimiter $$
CREATE TRIGGER mtCheck BEFORE INSERT ON t1
FOR EACH ROW
BEGIN
    set @action = NEW.myType;
IF (NEW.myType NOT LIKE 'B') THEN
            SET New.myType = 'C';
    END IF;
    set @action2 = NEW.myType;
END $$
delimiter ;

如果我运行下面的代码,因为 'A' 是 EMUN 的有效值,@action 是 'A' 而 @action2 是 'C':

set @action = 'no action';
set @action2 = 'no action';
select @action, @action2;
start transaction;
insert into t1(idt1, myType) values (1, 'A');
select @action, @action2;
select * from t1;
rollback;
select * from t1;
select @action, @action2;

如果我更改以下示例之一的插入语句,我会收到以下错误:

insert into t1(idt1, myType) values (1, 'F');

-> 错误 1265 (01000):第 1 行的列“myType”的数据被截断

insert into t1(idt1, myType) values (1, null);

-> 错误 1048 (23000):列 'myType' 不能为空

触发器不应该将新值强制输入 NEW.myType 字段并且插入语句继续使用正确的值吗?在这种情况下,两个示例都应在表 t1 的 myType 字段中输入值“C”。

它与我的 sql_mode 有什么关系吗?

SELECT @@GLOBAL.sql_mode;

-> STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

SELECT @@SESSION.sql_mode;

-> STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

我应该把它改成STRICT_ALL_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION?

4

1 回答 1

0

我相信我发现了我的错误。

为在事务中插入/更新原始表行而创建的临时表与原始表具有相同的限制。

如果此分析准确,则意味着在我插入/更新表行之前,数据库管理系统将验证正在插入/更新的值并返回上述错误,因为我没有提供有效数据。

在建立与数据库的连接之前,我必须将验证留给应用程序。

于 2012-08-01T18:04:02.280 回答