I have a trigger that I want to run before insert a row into a table:
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 ;
If I run the code below, since ‘A’ is a valid value for the EMUN, the @action is ‘A’ and the @action2 is ‘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;
If I change the insert statement for one of the following examples, I receive the following errors:
insert into t1(idt1, myType) values (1, 'F');
-> ERROR 1265 (01000): Data truncated for column ‘myType’ at row 1
insert into t1(idt1, myType) values (1, null);
-> ERROR 1048 (23000): Column ‘myType’ cannot be null
Shouldn’t the trigger force the new value into the NEW.myType field and the insert statement continue with the right values? In this case both examples should enter value ‘C’ at the myType field in table t1.
Does it have anything to do with my 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
Should I change it to STRICT_ALL_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION?
I believe that i found out my mistake.
The temporary table created to insert/update the original table rows within a transaction, has the same restrictions as the original table.
If this analysis is accurate, that means that before i can insert/update a table row, the database management system will validate the values that are being inserted/updated and will return the errors above, because i’m not providing valid data.
I will have to leave the validation to the application, before establishing the connection to the database.