JSON_EXTRACT在触发器中需前置JSON_VALID校验,用->>或JSON_UNQUOTE去引号,数字字段建议显式CAST,JSON比对须提取路径后类型一致比较。
触发器里直接用
提取 JSON 字段局部值是可行的,但必须绕过类型校验和空值陷阱,否则触发器会中断执行。
为什么
在触发器里常报错
MySQL 5.7 要求
的第一个参数必须是合法 JSON 类型值,而
实际上是
或
类型(即使列定义为
,在触发器上下文中也可能未被自动强转)。一旦字段为空、含非法字符或只是普通字符串,就会触发
错误,导致整个触发器失败。
必须前置判断,不能省略
若列定义为
但内容来自旧应用或迁移数据,仍可能存非 JSON 值(如
字符串而非真正的
)
对路径错误或键不存在不报错,但返回
;若后续赋值给非空列,会引发插入失败
返回值带引号,直接赋值会出问题
返回的是 JSON 类型值,比如
(带双引号),不是字符串
。如果把它直接赋给
列,MySQL 5.7 默认会保留引号,导致业务层看到的是
而非预期的
。
php版微信js-sdk支付接口类
php版微信js-sdk支付接口类
下载
必须用
去掉外层引号
或者改用
操作符(等价于
),写法更短:
对数字字段(如
),
返回的是 JSON 数字,MySQL 会隐式转为整数,但建议显式
避免边界异常(如
、科学计数法)
UPDATE 触发器中安全比对 JSON 内部字段是否变更
不能写
—— 这是字符串比较,顺序、空格、换行都影响结果,且无法识别语义等价的 JSON(如
和
)。
应提取具体路径并分别比对:
注意两边都用
或都用
,保持类型一致
若字段可能为
,需用
/
显式判断,避免
返回
(即 false)
数组或嵌套对象变更监控不推荐在触发器里做——性能差且逻辑复杂;只盯关键标量字段(
、
、
)更实际
BEFORE INSERT/UPDATE 中解析 JSON 并填充生成列或普通列
典型场景:用户提交
JSON,想自动拆出
和
存到对应列,便于索引和查询。
必须包裹在
中
是最简写法;若路径可能缺失,加
防止
写入非空列
不要在触发器里对本表做
或
—— 所有操作只能基于
和
行数据
大 JSON(>4KB)频繁解析会影响触发器性能;若字段更新频率低但解析开销高,可考虑延迟处理(如通过应用层或异步任务)
JSON_EXTRACTJSON_EXTRACT(NEW.json_col, '$.key')JSON_EXTRACTNEW.json_colTEXTVARCHARJSONInvalid JSON textJSON_VALID(NEW.json_col)JSON'null'NULLJSON_EXTRACTNULLJSON_EXTRACTJSON_EXTRACT"john"johnVARCHAR"john"johnJSON_UNQUOTE(JSON_EXTRACT(...))->>JSON_UNQUOTE(JSON_EXTRACT(...))NEW.json_col->>'$.name'ageJSON_EXTRACTCAST(... AS UNSIGNED)-0OLD.json_col != NEW.json_col{"a":1}{"a": 1}JSON_UNQUOTE(OLD.json_col->>'$.status') != JSON_UNQUOTE(NEW.json_col->>'$.status')->>JSON_UNQUOTE(JSON_EXTRACT())NULLIS NULLIS NOT NULLNULL != 'x'NULLstatuspriceupdated_byprofilenicknameemailIF JSON_VALID(NEW.profile) THEN ... END IF;SET NEW.nickname = NEW.profile->>'$.nickname';IFNULL(..., '')NULLSELECTUPDATENEWOLD