将MySQL触发器中的Null与另一个值进行比较

时间:2011-08-09 16:07:57

标签: mysql triggers null compare

所以这是我的问题我在更新表行时比较新旧值。但新旧值有时会为空。所以下面的代码不起作用。我可以解决这个问题吗?

谢谢

BEFORE UPDATE ON mytable
   FOR EACH ROW
BEGIN
        IF OLD.assignedto != NEW.assignedto
        THEN
                INSERT INTO history
                    (
                        asset    ,
                        changedfield     ,
                        oldvalue    ,
                        newvalue      
                    )
                    VALUES
                    (
                        NEW.asset,
                        'assignedto',
                        OLD.assignedto,
                        NEW.assignedto
                    );
        END IF;
    END$$

6 个答案:

答案 0 :(得分:15)

MySql有一个特殊的空安全等式检查操作符:

  

< =>

     

NULL-safe相等。此运算符执行与=运算符类似的相等比较,但如果两个操作数都返回1而不是NULL   如果一个操作数为NULL,则为NULL,而不是NULL。

mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
        -> 1, 1, 0
mysql> SELECT 1 = 1, NULL = NULL, 1 = NULL;
        -> 1, NULL, NULL

您可以将此运算符与NOT运算符一起使用:

mysql> SELECT NOT (1 <=> 1), NOT (NULL <=> NULL), NOT (1 <=> NULL);
        -> 0, 0, 1

所以,在你的情况下你应该写:

IF NOT (OLD.assignedto <=> NEW.assignedto)

答案 1 :(得分:3)

尝试:

IF (   (OLD.assignedto IS NOT NULL AND NEW.assignedto IS NOT NULL 
             AND OLD.assignedto != NEW.assignedto)
    OR (OLD.assignedto IS NULL AND NEW.assignedto IS NOT NULL)
    OR (OLD.assignedto IS NOT NULL AND NEW.assignedto IS NULL)
   )

评论非常正确。

答案 2 :(得分:1)

null必须与is null / is not null构造进行比较:

if ((old.assignedto != new.assignedto) or (old.assignedto is null) or (new.assignedto is null))

您必须根据自己的要求进行调整,因为如果其中任何一个为空或彼此不相等,则会返回true。也许您需要处理两者都为空的情况。

答案 3 :(得分:1)

您无法与NULL进行比较,因为NULL被定义为在比较中从不匹配的值,甚至是其他NULLS。如果你不相信我,请试试自己。

SELECT NULL = NULL;

您必须检查相关列是否为空且IS NOT NULL。您可以使用AND或OR运算符将此类测试合并到您已有的逻辑中。

答案 4 :(得分:1)

IF COALESCE(OLD.assignedto != NEW.assignedto, OLD.assignedto IS NULL AND NEW.assignedto IS NULL)

如果OLD.assignedto != NEW.assignedto部分有一个运算符NULL,则整个表达式获得NULL,使COALESCE()返回下一个参数,而返回真值以便使用其中NULL - 另一个也必须NULL

答案 5 :(得分:0)

我知道这很老了,但是写这种条件的方法稍微更清晰一些:

IF COALESCE(OLD.assignedto, 0) <> COALESCE(NEW.assignedto, 0) THEN ...

通过这种方式,您告诉引擎将NULL替换为0,以使条件与NULL比较不会失败。