web-dev-qa-db-ja.com

列の値がnullから1に変更されたときにトリガーが実行されない

私はこのトリガーを持っています:

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を実行して問題を解決しました。

3
Ankit Kapoor

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)
6
Philᵀᴹ
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;
2
vitro

これにより、不等式の大文字と小文字が区別されます

IF NOT(BINARY NEW.col1 <=> BINARY OLD.col1) 
    THEN UPDATE t2 SET col2 = 1 WHERE t2.col3 = t1.col3;
END IF;
0
Miguel Loureiro

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

$$
0
Pazuzu