→

MySQL →  Решение ошибки MySql 1442

Итак, имеем ошибку MySql 1442

Для рассмотрения проблемы в полевых условиях создадим таблицу:
CREATE TABLE `t1` (
`a` char(1) default NULL,
`b` smallint(6) default NULL
);
insert into t1 values ('y','1');

Она содержит поля a и b. Необходимо проапдейтить поле a до какого-то 'n', когда b = 0.
Решение 1:
DELIMITER |
CREATE TRIGGER trigger1 AFTER UPDATE ON t1
FOR EACH ROW UPDATE t1 SET a= 'n' WHERE b=0;
|
DELIMITER ;

Тригер создается на ура, но мы получаем сабжевую ошибку MySql 1442
Can’t update table ‘t1′ in stored function/trigger because it is already used by statement which invoked this stored function/trigger
когда пытаемся заапдейтить поле b в таблице t1.
mysql> update t1 set b=0;
ERROR 1442 (HY000): Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

Как мы уже поняли, дело в нашем тригере. Для решения проблемы, нам необходимо его переписать следующим образом:
drop trigger trigger1;
DELIMITER |
CREATE TRIGGER trigger1 BEFORE UPDATE ON t1
FOR EACH ROW
BEGIN
IF NEW.b=0 THEN
SET NEW.a = 'n';
END IF;
END
|
DELIMITER ;

С новым тригером ошибка вида «ERROR 1442 (HY000): Can’t update table ‘t1′ in stored function/trigger because it is already used by statement which invoked this stored function/trigger.» уже не вознимает при апдейте. Проверим?
mysql> update t1 set b=0;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from t1\G
*************************** 1. row ***************************
a: n
b: 0

Таким образом, если мы хотим создать тригер на таблицу, которая будет апдейтись себя по изменению на свои же поля, то нам необходимо использовать поле NEW.column_name, которое будет ссылаться на строку после апдейта и не делать полного апдейта.

Если же вы будете апдейтить другую таблицу, то первое решение вполне подойдет:
DELIMITER |
CREATE TRIGGER trigger1 AFTER UPDATE ON t1
FOR EACH ROW UPDATE t2 SET a= ‘n’ WHERE b=0;
|
DELIMITER ;
0