mysql触发器中用= null判断必然失效,因null不能用等号比较,结果为unknown;必须用is null或is not null才能正确触发分支。

触发器里用 = NULL 判断一定会失效
MySQL 触发器中写 IF NEW.age = NULL THEN,逻辑永远不执行。这不是语法错误,而是语义陷阱:NULL 不是值,不能用等号比较。任何 = NULL、!= NULL、 NULL 的结果都是 UNKNOWN,而触发器的 IF 只认 TRUE,UNKNOWN 等同于“不满足条件”。
必须用 IS NULL / IS NOT NULL 才能进分支
触发器内判断字段是否为 NULL,唯一可靠方式是 IS NULL 或 IS NOT NULL:
-
IF NEW.age IS NULL THEN ...—— 正确,命中 NULL 时执行 -
IF NEW.age IS NOT NULL THEN ...—— 正确,排除 NULL 后再处理有效值 - 别写
IF NEW.age NULL,它和= NULL一样无效
IFNULL() 是补救手段,不是判断替代品
IFNULL() 本身不用于判断,而是做“兜底替换”——当字段可能为 NULL 时,提前转成默认值再参与后续逻辑:
-
SET @safe_age = IFNULL(NEW.age, 0);把 NULL 转成 0,避免加法或比较出错 -
IF IFNULL(NEW.age, 0) > 18 THEN ...这样写可行,但本质是绕开 NULL 判断,不是真正检测 NULL - 如果业务需要区分“用户填了 0”和“用户没填(NULL)”,就不能用
IFNULL()掩盖差异
复杂场景建议组合使用 IS NULL + IFNULL
比如更新日志触发器既要记录“设为 NULL”,又要对非 NULL 值做校验:
IF NEW.phone IS NULL THEN
INSERT INTO log (msg) VALUES ('phone cleared');
ELSE
SET @cleaned = IFNULL(TRIM(NEW.phone), '');
IF @cleaned = '' THEN
INSERT INTO log (msg) VALUES ('phone is empty after trim');
END IF;
END IF;
这里 IS NULL 守住第一道边界,IFNULL() 在非 NULL 分支里防空格/空字符串干扰。漏掉任一环节,都可能让 NULL 渗透进后续字符串操作,导致意外截断或隐式转换。











