如何用SQL Server的OPENJSON提取JSON列指定字段并保留原类型返回
在SQL Server中用OPENJSON提取JSON列指定字段并保留JSON格式
需求:从SQL Server的JSON列中提取特定字段,同时保留JSON数据类型返回结果。由于JSON字段结构动态,无法提前确定字段类型来使用显式架构,示例中需要获取ConfigID和仅包含appName、isEnabled、domains、maxUsers字段的Data列(JSON格式)。
输入数据
| ConfigID | Name | Data |
|---|---|---|
| 1 | application1 | {"appName" : "app-1", "createdBy" : "John", "isEnabled" : false, "domains" : ["domain1","domain2","domain3"], "maxUsers" : 100} |
| 2 | application2 | {"appName" : "app-2", "createdBy" : "Peter", "isEnabled" : true, "domains" : ["domain1"], "site" : "abc.com" } |
期望输出
| ConfigID | Data |
|---|---|
| 1 | {"appName" : "app-1", "isEnabled" : false, "domains" : ["domain1","domain2","domain3"], "maxUsers" : 100} |
| 2 | {"appName" : "app-2", "isEnabled" : true, "domains" : ["domain1"] } |
实现查询
可以通过单个SQL查询结合OPENJSON、JSON_VALUE、JSON_QUERY和FOR JSON来实现,无需依赖应用代码处理:
SELECT ConfigID, JSON_QUERY(( SELECT -- 检查字段是否存在,存在则取值,不存在则不生成该键 CASE WHEN EXISTS(SELECT 1 FROM OPENJSON(Data) WHERE [key] = 'appName') THEN JSON_VALUE(Data, '$.appName') END AS appName, CASE WHEN EXISTS(SELECT 1 FROM OPENJSON(Data) WHERE [key] = 'isEnabled') THEN JSON_VALUE(Data, '$.isEnabled') END AS isEnabled, CASE WHEN EXISTS(SELECT 1 FROM OPENJSON(Data) WHERE [key] = 'domains') THEN JSON_QUERY(Data, '$.domains') END AS domains, CASE WHEN EXISTS(SELECT 1 FROM OPENJSON(Data) WHERE [key] = 'maxUsers') THEN JSON_VALUE(Data, '$.maxUsers') END AS maxUsers FOR JSON PATH, WITHOUT_ARRAY_WRAPPER )) AS Data FROM YourTableName; -- 替换为你的实际表名
逻辑说明
- 子查询中通过
EXISTS(SELECT 1 FROM OPENJSON(Data) WHERE [key] = '字段名')判断目标字段是否存在于当前行的JSON中; - 普通字段用
JSON_VALUE提取值,数组类型字段用JSON_QUERY避免被转义成字符串; FOR JSON PATH, WITHOUT_ARRAY_WRAPPER将筛选后的字段重新组合为单个JSON对象(而非数组);- 外层用
JSON_QUERY确保返回的Data列是JSON数据类型,而非字符串类型。
这种方式会自动忽略原JSON中不存在的目标字段,完全适配动态结构的需求。
内容的提问来源于stack exchange,提问作者rosayu8
相关产品推荐
相关产品推荐

