ISJSON在SQL Server 2022中仍为JSON语法校验首选,新增json_type_constraint参数支持VALUE、ARRAY、OBJECT、SCALAR四类类型约束,需按语义精准选用,配合计算列与筛选索引方可保障性能。

ISJSON 在 SQL Server 2022 中仍是校验 JSON 字符串语法合法性的首选函数,但它比旧版本多了类型约束能力——不光能判“是不是 JSON”,还能判“是不是你想要的那类 JSON”。
ISJSON(expression, json_type_constraint) 的 type 参数怎么选
SQL Server 2022 新增的 json_type_constraint 参数支持 VALUE、ARRAY、OBJECT、SCALAR 四种值,选错会导致误判:
-
OBJECT:只认{...}开头结尾的结构,{"a":1}返回 1,[{"a":1}]返回 0 -
ARRAY:只认[...],[]或[1,"x",{}]都行,但{"items":[]}返回 0 -
SCALAR:专用于校验 RFC 8259 兼容的“纯标量”顶层值,比如"hello"、42、true、null;注意'null'(字符串)返回 0,而null(字面量)返回 1 -
VALUE:最宽泛,覆盖对象、数组、标量三类,等价于不传第二个参数时的行为
常见报错和静默失败场景
ISJSON 不抛异常,但输入类型或内容不对时会返回 0 或 NULL,容易被忽略:
- 传入
TEXT或XML类型字段会直接报错,必须先CAST(col AS NVARCHAR(MAX)) - 带 UTF-8 BOM 的字符串(如以
0xEFBBBF开头)会被识别为非法字符,返回 0;建议入库前用REPLACE(LEFT(@s,3), NCHAR(0xFEFF), N'')清理 - 空字符串
''返回 0,'null'(小写字符串)返回 1,NULL输入返回NULL—— CHECK 约束中要额外加col IS NOT NULL才能禁 NULL - 键名重复、数字溢出(如
999999999999999999999)、控制字符(U+0000)均不会触发错误,ISJSON只做语法扫描
在存储过程里安全调用 ISJSON 的惯用写法
别等 JSON_VALUE 返回 NULL 才发现问题,校验必须前置:
IF ISJSON(@input) = 0
BEGIN
RAISERROR('Invalid JSON format in @input', 16, 1);
RETURN;
END
<p>-- 若需强约束为对象,用:
IF ISJSON(@input, OBJECT) = 0
BEGIN
RAISERROR('Expected JSON object, got %s', 16, 1, @input);
RETURN;
END注意:不要写 ISJSON(@input) > 0,因为返回 NULL 时整个条件为 UNKNOWN,逻辑失效;必须显式写 = 1 或 = 0。
WHERE 条件中用 ISJSON 的性能陷阱
直接写 WHERE ISJSON(json_col) = 1 无法利用 json_col 上的普通索引,执行计划必是全表扫描:
- 高频查询场景下,应建计算列:
ALTER TABLE logs ADD json_valid AS ISJSON(payload); - 再建筛选索引:
CREATE INDEX IX_logs_valid_json ON logs(json_valid) WHERE json_valid = 1; - WHERE 子句改用
WHERE json_valid = 1 AND ...,才能走索引
真正容易被忽略的是:即使你加了 CHECK 约束,SQL Server 也不会自动为 ISJSON() 表达式建统计信息,优化器对它的选择性预估极不准,所以计算列 + 筛选索引不是可选项,而是必要项。


















