私はこのトリガーを持っています:
delimiter $$
create trigger tr
after update on t1
for each row
begin
if new.col1 !=old.col1
then update t2 set col2 =1 where t2.col3=t1.col3;
end if;
end
$$
このトリガーは、col1
の値が0から1に変更された場合に機能しますが、nullから1に変更された場合、トリガーはt2
を変更しません。
なぜそうなのか知りたかったのです。 nullが異なることはわかっていますが、値を比較しているだけです。
new.col1 =1
を実行して問題を解決しました。
If条件を次のように変更します。
if (new.col1 != old.col1) or ( new.col1 is not null and old.col1 is null )
or ( old.col1 is not null and new.col1 is null )
これで問題が解決するはずです。 NULL
値との等価性をテストできないため、元のコードは正しく機能しませんでした。IS NULL
またはIS NOT NULL
を使用する必要があります。
MySQLには "null-safe equals"演算子もあります:<=>
これを使用して、上記の条件をより簡単にすることができます(それでも同等です):
if not (new.col1 <=> old.col1)
IF !(NEW.col1 <=> OLD.col1)
THEN UPDATE t2 SET col2 = 1 WHERE t2.col3 = t1.col3;
END IF;
説明:
<=>は、MySQLマニュアルのnullセーフオペレーターです。
mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
-> 1, 1, 0
mysql> SELECT 1 = 1, NULL = NULL, 1 = NULL;
-> 1, NULL, NULL
ただし、このトリガーはcol1
の値が1からNULL
に変化します。それが必要かどうかはわかりません。
この動作を望まない場合は、この方法で条件を書き直すことができます。
IF (!(NEW.col1 <=> OLD.col1) AND NEW.col1 IS NOT NULL)
THEN UPDATE t2 SET col2 = 1 WHERE t2.col3 = t1.col3;
END IF;
これにより、不等式の大文字と小文字が区別されます
IF NOT(BINARY NEW.col1 <=> BINARY OLD.col1)
THEN UPDATE t2 SET col2 = 1 WHERE t2.col3 = t1.col3;
END IF;
Ifnullを使用してチェックおよび比較します。以下は、実際のデータとして「xxxxxx」がないことを前提とした例です。
delimiter $$
create trigger tr
after update on t1
for each row
begin
if (ifnull(new.col1,'xxxxxx') != ifnull(old.col1,'xxxxxx'))
then update t2 set col2 =1 where t2.col3=t1.col3;
end if;
end
$$