ISJSON()是SQL Server 2016+唯一原生JSON语法校验函数,返回1/0/NULL;仅校验语法,不检查语义或业务规则,且低版本及其他数据库需用JSON_VALID()或jsonb转换等替代方案。

SQL Server 2016+ 中 ISJSON() 是唯一原生、可靠、高性能的 JSON 格式校验函数;低版本或其它数据库(如 MySQL、PostgreSQL)不支持该函数,需改用其他策略。
ISJSON() 函数的基本用法和返回值含义
ISJSON() 接收一个 varchar 或 nvarchar 类型的字符串参数,返回 INT:返回 1 表示字符串是合法 JSON(语法正确),返回 0 表示不是,返回 NULL 表示输入为 NULL。它只校验语法,不检查语义(比如字段名重复、数字溢出等不会报错)。
常见误用点:
- 传入
TEXT或XML类型会报错,必须显式转成varchar(max)或nvarchar(max) - 空字符串
''返回0,不是合法 JSON;'null'(小写)返回1,是合法 JSON 字面量 - 带 BOM 的 UTF-8 字符串可能被误判为非法(SQL Server 默认按 Unicode 解析,BOM 会导致开头出现不可见字符)
在 WHERE 和 CHECK 约束中安全使用 ISJSON()
直接在查询条件中用 ISJSON(json_col) = 1 可过滤出合法 JSON 记录,但要注意执行计划是否能走索引——ISJSON() 是计算列函数,无法直接利用普通列索引。若高频校验,建议建计算列 + 索引:
ALTER TABLE logs ADD json_valid AS ISJSON(payload); CREATE INDEX IX_logs_json_valid ON logs(json_valid) WHERE json_valid = 1;
在表定义中加 CHECK 约束可强制入库校验:
ALTER TABLE config ADD CONSTRAINT CHK_payload_json CHECK (ISJSON(payload) = 1);
注意:CHECK 约束对 NULL 默认放行(因为 ISJSON(NULL) 返回 NULL,而 NULL = 1 判定为未知,不触发约束失败),如需禁止 NULL,要额外写 payload IS NOT NULL。
MySQL / PostgreSQL 怎么替代 ISJSON()?
MySQL 5.7+ 提供 JSON_VALID(),行为与 ISJSON() 高度一致,用法相同:JSON_VALID(json_str) = 1。但注意:MySQL 对 trailing comma、重复 key 的容忍度更低,某些 SQL Server 认为合法的 JSON(如 {"a":1,})在 MySQL 中会返回 0。
PostgreSQL 没有内置标量函数,常用两种方式:
- 用
jsonb '尝试强转,配合your_string'DO $$ BEGIN ... EXCEPTION WHEN invalid_text_representation THEN ... END $$捕获异常(仅适用于 PL/pgSQL 上下文) - 更实用的是在应用层或视图中用
jsonb_path_exists(jsonb_col, '$')—— 虽不严格等价,但对绝大多数合法 JSON 返回 true,且性能可接受
跨数据库迁移时,别假设 ISJSON() 的结果在其它系统里完全一致;尤其注意空格、换行、Unicode 转义、NaN/Infinity 等边界情况。
ISJSON() 不能代替业务逻辑校验
它只回答“这串字符能不能被解析成 JSON”,不回答“这 JSON 是否符合我的业务 schema”。例如:
-
'{"user_id": "abc", "age": "twenty"}'会被ISJSON()认为合法,但user_id应为整数、age应为数字——这些得靠后续JSON_VALUE()+ 类型转换 + 条件判断 -
'{"items": [1,2,3], "items": ["a","b"]}'在 SQL Server 中是合法 JSON(重复 key 被后一个覆盖),但业务上可能要求 key 唯一
真正上线前,务必用真实脏数据集测试:含控制字符、超长嵌套、混合编码、半截转义的字符串,ISJSON() 很容易给出“假阳性”结果。











