openjson不加with只能返回key、value、type三列,无法用于业务查询;必须用with显式声明字段名、类型及json路径(如id int '$.id'),路径须以$开头,数组需指定路径或用cross apply分层展开。

OPENJSON不加WITH只能看结构,不能当业务表用
直接执行 OPENJSON(@json) 只会返回三列:key、value、type,看着像解析成功了,但根本没法 JOIN、WHERE 或插入目标表。你看到的“数据没出来”,90%是漏写了 WITH 子句。
必须显式声明字段名、类型和路径,例如:
SELECT * FROM OPENJSON(@json) WITH (id INT '$.id', name NVARCHAR(50) '$.name', active BIT '$.is_active');
-
WITH是强制项,不是可选项 - 列名可以和 JSON key 不同(比如 JSON 里是
user_id,你映射成id INT '$.user_id'完全合法) - 路径必须以
$开头,写成'id INT 'user_id''或'id INT '.user_id''都静默返回NULL
JSON数组在根层级 vs 嵌套在对象里,调用方式完全不同
如果 JSON 是纯数组:N'[{"id":1},{"id":2}]',直接 OPENJSON(@json) 就能展开成两行;但如果数组藏在对象下:N'{"data":[{"id":1},{"id":2}]}',就必须指定路径:OPENJSON(@json, '$.data'),否则只解析外层对象,data 数组本身被当做一个值(type = 4),不会展开。
- 数组索引从 0 开始:
'$[0].name'才是第一个元素的name,别写'$[1].name' - 传入非数组/非对象的 JSON(比如字符串
"hello")会导致OPENJSON返回空结果集,不报错也不提示 - 调试时先用
ISJSON(@json)确认输入合法,再查sys.dm_exec_describe_first_result_set(N'SELECT * FROM OPENJSON(@j)', N'@j NVARCHAR(MAX)', 0)看实际输出结构
嵌套数组必须用CROSS APPLY分层展开,不能靠一层WITH硬写
面对这种结构:{"orders": [{"id":1,"items":[{"sku":"A"},{"sku":"B"}]},{"id":2,"items":[{"sku":"C"}]}]},别试图在第一层 WITH 里写 sku NVARCHAR(20) '$.orders[0].items[0].sku'——这只会取到第一个订单的第一个商品,且无法关联多行数据。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
正确做法是分两步:
SELECT o.id, i.sku FROM OPENJSON(@json, '$.orders') WITH (id INT '$.id') AS o CROSS APPLY OPENJSON(@json, '$.orders[' + CAST(o.id - 1 AS VARCHAR) + '].items') WITH (sku NVARCHAR(20) '$.sku') AS i;
- 更稳的方式是先展开
orders,再对每行结果CROSS APPLY OPENJSON(value, '$.items'),避免拼接路径出错 - 注意
value列来自上层OPENJSON的默认输出,它包含当前数组元素的完整 JSON 字符串 - 深层嵌套会让
CROSS APPLY链变长,容易漏掉某一层的WITH类型声明,导致整行NULL
路径错、类型不匹配、空值都返回NULL,不是数据真为空
JSON_VALUE 和 OPENJSON 默认对路径错误、类型不兼容、JSON 值为 null 全部静默返回 NULL。你在查询里看到一堆 NULL,大概率不是数据缺失,而是路径写错了或者类型声明不合理。
- 开发阶段务必在
JSON_VALUE后加ERROR ON ERROR,例如:JSON_VALUE(@json, '$.user.profile.phone' ERROR ON ERROR),一错立刻中断并提示具体路径问题 -
OPENJSON本身不支持ERROR ON ERROR,但你可以用JSON_VALUE先抽几个关键字段验证路径是否可达 - 类型要跟 JSON 实际值一致:JSON 里
"age": "25"(字符串)配INT会返回NULL;"active": "true"配BIT同样失败 - 数据库兼容级别必须 ≥ 130,低于这个值
OPENJSON函数根本不可用,查SELECT compatibility_level FROM sys.databases WHERE name = DB_NAME()确认
嵌套越深,路径和类型匹配的容错空间越小,一个点号位置错、一个引号漏掉、一个索引偏移没对齐,结果就是整列 NULL —— 而且你还看不出哪错了。










