2012-07-30 60 views
0

我有我想要运行之前插入一行到表中的触发器:之前插入触发器不设置值分析insert语句之前

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’和@动作2是‘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):数据被截断为列 '的myType' 在第1行

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

回答

0

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

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

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

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