2012-07-30 61 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

我相信我發現了我的錯誤。

爲插入/更新事務中的原始錶行而創建的臨時表具有與原始表相同的限制。

如果這種分析是準確的,這意味着在我可以插入/更新表格行之前,數據庫管理系統將驗證正在插入/更新的值並返回上面的錯誤,因爲我沒有提供有效的數據。

在建立與數據庫的連接之前,我將不得不將驗證留給應用程序。