valor - convertir null en 0 mysql
Manejo NULL en MySQL después del disparador de actualización que solo se activa en el cambio de datos (2)
Debido a restricciones de reputación, esta es una pregunta de seguimiento a esta respuesta a una pregunta anterior . Me gustaría saber si hay una manera más eficiente de probar cada campo para detectar cambios al manejar valores NULL.
CREATE TABLE foo (
a INT NULL DEFAULT NULL,
b INT NULL DEFAULT NULL,
c INT NULL DEFAULT NULL
);
CREATE TABLE bar (
a INT NULL DEFAULT NULL,
b INT NULL DEFAULT NULL,
c INT NULL DEFAULT NULL
);
INSERT INTO foo (a, b) VALUES (1, 2);
Quiero un disparador cuyas acciones ocurran después de la actualización solo si la actualización cambia un valor. Por lo tanto, esta ACTUALIZACIÓN no dará como resultado un INSERTAR:
UPDATE foo SET a = 1 WHERE b = 2;
Pero esta ACTUALIZACIÓN dará como resultado un INSERTO:
UPDATE foo SET a = 2 WHERE b = 2;
He escrito este disparador para manejar eso, sin embargo, espero que la declaración IF se pueda simplificar.
DELIMITER ///
CREATE TRIGGER t_after_update_foo
AFTER UPDATE ON foo
FOR EACH ROW
BEGIN
IF
((OLD.a <> NEW.a OR OLD.a IS NULL OR NEW.a IS NULL) AND (NEW.a IS NOT NULL OR OLD.a IS NOT NULL))
OR
((OLD.b <> NEW.b OR OLD.b IS NULL OR NEW.b IS NULL) AND (NEW.b IS NOT NULL OR OLD.b IS NOT NULL))
OR
((OLD.c <> NEW.c OR OLD.c IS NULL OR NEW.c IS NULL) AND (NEW.c IS NOT NULL OR OLD.c IS NOT NULL))
THEN
INSERT INTO bar (a, b, c) VALUES (NEW.a, NEW.b, NEW.c);
END IF;
END;
///
DELIMITER ;
¿Se puede simplificar la declaración IF? ¿O hay una solución general más fácil?
Puede usar coalesce()
, que devuelve el primero de sus argumentos que not null
es not null
.
if coalesce(old.a,'''') <> coalesce(new.a,'''') or
coalesce(old.b,'''') <> coalesce(new.b,'''') or
coalesce(old.c,'''') <> coalesce(new.c,'''')
then
insert ...;
end if;
Puede ser complicado elegir el segundo argumento. El ejemplo anterior funciona para el caso común cuando a, byc son cadenas y cuando un valor de cadena vacío es equivalente a un valor null
.
Puede hacer esto comparando usando el operador igual a NULL-safe <=>
y luego negando el resultado usando NOT
.
Asi que,
((OLD.a <> NEW.a OR OLD.a IS NULL OR NEW.a IS NULL) AND (NEW.a IS NOT NULL OR OLD.a IS NOT NULL))
se convertiría
!(OLD.a <=> NEW.a)
Para verificar si alguna de las múltiples columnas ha cambiado, puede hacer
!(OLD.a <=> NEW.a AND OLD.b <=> NEW.b)