能,ISJSON函数在SQL Server 2016+中可直接校验字符串是否为合法JSON,仅检查基础语法(括号、引号、值类型等),返回1表示合法,0或NULL表示不合法,不校验语义或业务规则。

ISJSON 函数能直接判断字符串是否合法 JSON 吗?
能,但仅限于 SQL Server 2016 及以上版本。它不解析结构语义(比如字段名重复、数字溢出),只做基础语法校验:括号配对、引号闭合、键名是否带引号、值类型是否符合 JSON 标准(null、true、false、字符串、数字、数组、对象)。返回 1 表示通过,0 或 NULL 表示不合法。
INSERT 前用 ISJSON 防止非法 JSON 写入的写法
别在应用层做校验再发 SQL —— 网络传输或并发下仍有风险。直接在 SQL 层拦截最可靠。常见写法是把 ISJSON() 放进 CHECK 约束或 INSERT ... SELECT 的 WHERE 条件里:
INSERT INTO logs (id, payload) SELECT @id, @payload WHERE ISJSON(@payload) = 1;
如果想让失败更明确,可配合 THROW:
IF ISJSON(@payload) 1
THROW 50000, 'payload is not valid JSON', 1;
INSERT INTO logs (id, payload) VALUES (@id, @payload);
-
@payload必须是NVARCHAR(MAX)类型,否则ISJSON返回NULL(不是0)导致条件失效 - 空字符串
''、纯空白(如' ')、NULL均返回0,符合预期 - 注意单引号转义:传入的 JSON 字符串本身含单引号时,SQL Server 不会自动转义,需在应用层处理或用
REPLACE预清洗
ISJSON 和 JSON_VALUE/JSON_QUERY 联用时的坑
ISJSON 通过 ≠ 数据能被 JSON_VALUE 正确提取。例如:{"a": 1, "a": 2} 是语法合法 JSON(某些解析器接受),ISJSON 返回 1,但 JSON_VALUE 只取最后一个 "a";又如 {"x": 999999999999999999999} 超出 float 精度,ISJSON 仍返回 1,但后续解析可能失真。
- 若业务依赖字段存在性或数值精度,不能只靠
ISJSON,得加TRY_CAST(... AS bigint)或正则预筛数字范围 -
JSON_QUERY对非对象/数组返回NULL,但ISJSON仍为1,所以想确保是对象得写ISJSON(@json) = 1 AND JSON_QUERY(@json, '$') IS NOT NULL - SQL Server 不校验 Unicode 代理对(surrogate pair),
"\uD83D\uDE00"(?)能过ISJSON,但某些客户端解析异常
替代方案:什么时候不该用 ISJSON?
MySQL 和 PostgreSQL 没有原生 ISJSON。MySQL 8.0+ 用 JSON_VALID(),PostgreSQL 则需自定义函数或靠 jsonb 类型强制校验(插入时自动拒绝非法 JSON)。如果数据库不支持,或者字段要频繁做路径查询,直接用 JSON / JSONB 类型比 NVARCHAR + ISJSON 更省心——类型本身就会拦截非法输入,无需额外判断。
ISJSON 是轻量兜底,不是万能解析器。真正关键的字段结构约束,得靠应用层 Schema 校验或数据库 CHECK 表达式组合实现。











