isjson()是sql server 2016+唯一原生json语法校验函数,返回1表示语法合法,0表示非法,null表示输入为null;仅校验括号、引号、转义等基础语法,不检查字段存在性、类型或业务规则。

SQL Server 2016+ 中 ISJSON() 是唯一可靠的内置校验函数
SQL Server 不提供 JSON Schema 验证或结构深度校验能力,ISJSON() 是判断字符串是否为合法 JSON 的唯一原生方式。它只检查语法有效性(如括号匹配、引号闭合、转义字符),不校验字段是否存在、类型是否匹配或值是否在业务范围内。
常见误用是把 ISJSON() 当作“业务规则检查”——比如期望 {"id": 1, "name": "a"},却对 {"id": "1", "name": null} 放行,后者也完全合法。
-
ISJSON()返回 1 表示语法合规,0 或 NULL 表示非法(含 NULL 输入) - 必须配合
TRY_PARSE_JSON()(SQL Server 2022+)才能进一步提取并校验字段类型,旧版本只能靠JSON_VALUE()+ISNULL()组合试探 - 触发器中调用
ISJSON()性能开销极低,但频繁解析大 JSON(>1MB)可能拖慢 INSERT/UPDATE
在 AFTER INSERT/UPDATE 触发器中校验 JSON 字段的典型写法
不要用 INSTEAD OF —— 它会绕过约束和默认值,且 JSON 校验失败时需手动回滚,逻辑更重。直接在 AFTER 触发器里抛出错误即可中断事务。
关键点:必须遍历 inserted 表逐行检查,不能只查第一行;错误信息要包含具体行标识(如主键),否则调试困难。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
CREATE TRIGGER tr_validate_json_payload
ON dbo.orders
AFTER INSERT, UPDATE
AS
BEGIN
IF EXISTS (
SELECT 1
FROM inserted i
WHERE ISJSON(i.payload) = 0
)
BEGIN
DECLARE @bad_id INT = (SELECT TOP 1 id FROM inserted WHERE ISJSON(payload) = 0);
THROW 50000, 'Invalid JSON in payload for order ID: ' + CAST(@bad_id AS VARCHAR(10)), 1;
END
END;
- 避免在 WHERE 条件里直接用
ISJSON(payload) = 0后接SELECT *—— 可能因多行失败导致THROW报错信息不明确 - 若表有复合主键,需拼接多个字段到错误消息中,例如
CAST(i.order_no AS VARCHAR) + '-' + i.version - SQL Server 2019 及以下版本不支持
JSON_SCHEMA_VALIDATION,别试图用OPENJSON模拟 Schema 校验——性能差且无法覆盖嵌套缺失字段
当需要校验 JSON 内部字段存在性或类型时,用 JSON_VALUE() + ISNULL() 组合兜底
例如要求 payload 必须含字符串型 customer_id 和数字型 total,仅靠 ISJSON() 不够。此时需分步提取并判空/类型:
-- 示例:校验 customer_id 存在且为非空字符串,total 存在且可转为数字
IF EXISTS (
SELECT 1 FROM inserted i
WHERE ISJSON(i.payload) = 0
OR JSON_VALUE(i.payload, '$.customer_id') IS NULL
OR JSON_VALUE(i.payload, '$.total') IS NULL
OR TRY_CONVERT(DECIMAL(10,2), JSON_VALUE(i.payload, '$.total')) IS NULL
)
BEGIN
THROW 50000, 'Missing or invalid required fields in payload', 1;
END
-
JSON_VALUE()对不存在路径返回 NULL,所以用ISNULL()或直接IS NULL判断比用JSON_QUERY()更安全 -
TRY_CONVERT()比ISNUMERIC()可靠,后者对'.'、'e3'等都返回 1,但无法转成 DECIMAL - 嵌套对象(如
$.address.city)需确保路径完整,中间任一节点缺失即整条路径返回 NULL —— 这是优点,不是 bug
生产环境必须注意的三个隐形陷阱
触发器里的 JSON 校验看似简单,但上线后最容易在这些地方翻车:
- 空字符串
''、空白符' '、NULL均被ISJSON()判为 0,但应用层可能传了空格包裹的 JSON,需前置TRIM()(SQL Server 2017+) - 触发器不会自动处理
UPDATE时 JSON 字段未被修改的情况 —— 如果业务允许部分更新,得加UPDATE(payload)判断避免无谓校验 - SQL Server 日志中不会记录触发器抛出的
THROW错误堆栈,排查时务必在错误消息里塞入足够上下文(如@@SPID、HOST_NAME())
真正难的不是写校验逻辑,而是定义清楚:哪些字段是强约束,哪些可以宽松;JSON 是只读载体还是会被后续存储过程反复解析 —— 这些决策直接影响触发器里该做多深的检查。










