所以这是我的问题我在更新表行时比较新旧值。但新旧值有时会为空。所以下面的代码不起作用。我可以解决这个问题吗?
谢谢
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$$
答案 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比较不会失败。