json_query用于提取json对象或数组并返回合法json字符串,json_value仅提取标量值并返回sql原生类型;路径前加lax(默认)或strict控制容错,嵌套结构必须用json_query配合for json使用。

JSON_QUERY 和 JSON_VALUE 的分工必须分清
JSON_QUERY 专用于提取 JSON 对象或数组,返回结果仍是合法 JSON(类型为 NVARCHAR(MAX) 或 CLOB),不会自动转义或去引号;而 JSON_VALUE 只能取标量值(字符串、数字、布尔、null),返回的是普通 SQL 类型,且会自动去掉外层双引号。如果误用 JSON_VALUE 去取一个对象字段,比如 '$.data',它会返回 NULL(除非该路径下恰好是字符串)。
路径表达式末尾加 lax 或 strict 控制容错行为
Oracle 和 SQL Server 都支持在路径前加 lax(默认)或 strict。用 lax 时,路径不存在、类型不匹配都返回 NULL;用 strict 则直接报错。生产环境建议显式写 lax $.items,避免因路径拼写错误导致整个查询失败。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
-
JSON_QUERY(json_col, 'lax $.user.profile')→ 安全取对象 -
JSON_QUERY(json_col, 'strict $.user.profile')→ 调试时快速暴露路径问题 - 省略修饰符等价于
lax,但显式写出更易维护
嵌套数组必须用 JSON_QUERY,不能靠 ->> 或 JSON_VALUE
假设字段 details 是 [{"id":1,"name":"a"},{"id":2,"name":"b"}],想完整取出这个数组:用 JSON_VALUE(details, '$[0].name') 只能取第一个元素的 name;用 details->>'$[0]'(PostgreSQL 风格)在 SQL Server 不合法;只有 JSON_QUERY(details, '$') 或 JSON_QUERY(details, '$[0]') 才能原样返回子对象或子数组。
- 错误写法:
JSON_VALUE(details, '$')→ 返回NULL(因为$指向整个数组,不是标量) - 正确写法:
JSON_QUERY(details, '$')→ 返回原始 JSON 字符串 - 若字段本身是字符串而非 JSON 类型,先用
ISJSON()检查,否则JSON_QUERY直接返回NULL
和 FOR JSON 组合时,JSON_QUERY 是嵌套结构的唯一出口
SQL Server 中生成嵌套 JSON 必须靠 FOR JSON PATH + 子查询,而子查询结果默认是字符串,要让它被识别为内嵌 JSON 对象/数组,必须包裹 JSON_QUERY()。否则 "items":"[{\"id\":1}]"(带引号的字符串),而不是 "items":[{"id":1}](真正的数组)。
- 子查询别名不能含点号,如
items.id,否则会被FOR JSON PATH自动转成嵌套对象,干扰预期结构 -
JSON_QUERY的第二个参数路径可以是'$',表示整个值;也可以是具体路径,如'$.results' - 若子查询返回空集,
JSON_QUERY(NULL, '$')仍返回NULL,外层FOR JSON会跳过该字段——这点和空数组[]不同,需提前用COALESCE(..., '[]')处理
{"a":1} 但列类型是 VARCHAR),只要内容合法,它就能提取;但如果内容是 {a:1}(缺引号),ISJSON 就过不了,JSON_QUERY 也返回 NULL —— 这类数据得先清洗,不能只靠函数兜底。










