MS SQL 查询包含 JSON 的字段
MS SQL Query a field containing JSON
我在 table 的 SQL 字段中有以下 JSON:
{
"type": "info",
"date": "2019/11/12 14:28:51",
"state": {
"6ee8587f-3b8c-4e5c-89a9-9f04752607f0": {
"state": "open",
"color": "#0000ff"
}
},
...
}
我在 MS SQL 中使用以下查询:
SELECT
JSON_VALUE(json_data, '$.type') AS msg_type
,JSON_VALUE(json_data, '$."date"') AS event_date
,JSON_QUERY(json_data, '$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0".state') AS json_state
,JSON_QUERY(json_data, '$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0".color') AS json_color
FROM
[dbo].[tbl_json_dump]
要取回日期(保留字),我必须将字段名称放在 $."date"
中
我似乎无法取回状态或颜色字段的数据,我认为这与它嵌套在“6ee8587f-3b8c-4e5c-89a9-9f04752607f0”下有关,因为当我查询时:
JSON_QUERY(json_data, '$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0"') AS json_state
我拿回了对象 -
{"state":"open","color":"#0000ff"}
但使用
JSON_QUERY(json_data, '$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0".state') AS json_state
它不起作用
对我做错了什么有什么建议吗??
只需将 JSON_QUERY
替换为 JSON_VALUE
,因为您有兴趣获取该值。
JSON_QUERY
应该是 return 一个 JSON 片段,旨在处理对象和数组,而不是值。
您可以尝试另一种可能的方法(更复杂),它解析所有嵌套的 JSON 对象。
Table:
CREATE TABLE Data (
JsonData nvarchar(max)
)
INSERT INTO Data
(JsonData)
VALUES
(N'{
"type": "info",
"date": "2019/11/12 14:28:51",
"state": {
"6ee8587f-3b8c-4e5c-89a9-9f04752607f0": {
"state": "open",
"color": "#0000ff"
},
"6ee8587f-3b8c-4e5c-89a9-9f04752607f1": {
"state": "open",
"color": "#0000ff"
}
}
}')
声明:
SELECT
j1.[type], j1.[date], j2.[key], j3.state, j3.color
FROM Data d
CROSS APPLY OPENJSON(d.JsonData) WITH (
[type] nvarchar(100) '$.type',
[date] datetime '$.date',
[state] nvarchar(max) '$.state' AS JSON
) j1
CROSS APPLY OPENJSON(j1.state) j2
CROSS APPLY OPENJSON(j2.[value]) WITH (
state nvarchar(10) '$.state',
color nvarchar(10) '$.color'
) j3
结果:
type date key state color
info 12/11/2019 14:28:51 6ee8587f-3b8c-4e5c-89a9-9f04752607f0 open #0000ff
info 12/11/2019 14:28:51 6ee8587f-3b8c-4e5c-89a9-9f04752607f1 open #0000ff
备注:
如果输入 JSON
在 "state"
JSON
对象中只有一个键 "6ee8587f-3b8c-4e5c-89a9-9f04752607f0"
,您可以使用正确的 JSON_VALUE()
获取值路径 $.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0".state
.
Salman A 已经给出了答案。补充几点。
JSON_VALUE()
- 提取标量值
JSON_QUERY()
- 从 JSON 字符串中提取对象或数组。
如果您看到语法,JSON_QUERY ( expression [ , path ] )
和 JSON_VALUE ( expression , path )
,除了 path
的 []
方括号外,两者或多或少都是可选的。这是因为 JSON_QUERY()
可以根据需要提取整个 JSON 字段。
并且在 return 类型上,
JSON_VALUE()
returns JSON 类型 nvarchar(max)
的片段
JSON_QUERY()
returns 类型为 nvarchar(4000)
的单个文本值
整体比较
DECLARE @data NVARCHAR(4000)
SET @data=N'{
"type": "info",
"date": "2019/11/12 14:28:51",
"state": {
"6ee8587f-3b8c-4e5c-89a9-9f04752607f0": {
"state": "open",
"color": "#0000ff"
}
},
}'
SELECT
JSON_VALUE(@data,'$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0"') AS 'JSON_VALUE_FAILED',
JSON_QUERY(@data,'$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0"') AS 'JSON_QUERY_SUCCEED',
JSON_VALUE(@data,'$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0".state') AS 'JSON_VALUE_SUCCEED',
JSON_QUERY(@data,'$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0".state') AS 'JSON_QUERY_SUCCEED';
我在 table 的 SQL 字段中有以下 JSON:
{
"type": "info",
"date": "2019/11/12 14:28:51",
"state": {
"6ee8587f-3b8c-4e5c-89a9-9f04752607f0": {
"state": "open",
"color": "#0000ff"
}
},
...
}
我在 MS SQL 中使用以下查询:
SELECT
JSON_VALUE(json_data, '$.type') AS msg_type
,JSON_VALUE(json_data, '$."date"') AS event_date
,JSON_QUERY(json_data, '$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0".state') AS json_state
,JSON_QUERY(json_data, '$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0".color') AS json_color
FROM
[dbo].[tbl_json_dump]
要取回日期(保留字),我必须将字段名称放在 $."date"
中我似乎无法取回状态或颜色字段的数据,我认为这与它嵌套在“6ee8587f-3b8c-4e5c-89a9-9f04752607f0”下有关,因为当我查询时:
JSON_QUERY(json_data, '$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0"') AS json_state
我拿回了对象 -
{"state":"open","color":"#0000ff"}
但使用
JSON_QUERY(json_data, '$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0".state') AS json_state
它不起作用
对我做错了什么有什么建议吗??
只需将 JSON_QUERY
替换为 JSON_VALUE
,因为您有兴趣获取该值。
JSON_QUERY
应该是 return 一个 JSON 片段,旨在处理对象和数组,而不是值。
您可以尝试另一种可能的方法(更复杂),它解析所有嵌套的 JSON 对象。
Table:
CREATE TABLE Data (
JsonData nvarchar(max)
)
INSERT INTO Data
(JsonData)
VALUES
(N'{
"type": "info",
"date": "2019/11/12 14:28:51",
"state": {
"6ee8587f-3b8c-4e5c-89a9-9f04752607f0": {
"state": "open",
"color": "#0000ff"
},
"6ee8587f-3b8c-4e5c-89a9-9f04752607f1": {
"state": "open",
"color": "#0000ff"
}
}
}')
声明:
SELECT
j1.[type], j1.[date], j2.[key], j3.state, j3.color
FROM Data d
CROSS APPLY OPENJSON(d.JsonData) WITH (
[type] nvarchar(100) '$.type',
[date] datetime '$.date',
[state] nvarchar(max) '$.state' AS JSON
) j1
CROSS APPLY OPENJSON(j1.state) j2
CROSS APPLY OPENJSON(j2.[value]) WITH (
state nvarchar(10) '$.state',
color nvarchar(10) '$.color'
) j3
结果:
type date key state color
info 12/11/2019 14:28:51 6ee8587f-3b8c-4e5c-89a9-9f04752607f0 open #0000ff
info 12/11/2019 14:28:51 6ee8587f-3b8c-4e5c-89a9-9f04752607f1 open #0000ff
备注:
如果输入 JSON
在 "state"
JSON
对象中只有一个键 "6ee8587f-3b8c-4e5c-89a9-9f04752607f0"
,您可以使用正确的 JSON_VALUE()
获取值路径 $.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0".state
.
Salman A 已经给出了答案。补充几点。
JSON_VALUE()
- 提取标量值
JSON_QUERY()
- 从 JSON 字符串中提取对象或数组。
如果您看到语法,JSON_QUERY ( expression [ , path ] )
和 JSON_VALUE ( expression , path )
,除了 path
的 []
方括号外,两者或多或少都是可选的。这是因为 JSON_QUERY()
可以根据需要提取整个 JSON 字段。
并且在 return 类型上,
JSON_VALUE()
returns JSON 类型 nvarchar(max)
JSON_QUERY()
returns 类型为 nvarchar(4000)
整体比较
DECLARE @data NVARCHAR(4000)
SET @data=N'{
"type": "info",
"date": "2019/11/12 14:28:51",
"state": {
"6ee8587f-3b8c-4e5c-89a9-9f04752607f0": {
"state": "open",
"color": "#0000ff"
}
},
}'
SELECT
JSON_VALUE(@data,'$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0"') AS 'JSON_VALUE_FAILED',
JSON_QUERY(@data,'$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0"') AS 'JSON_QUERY_SUCCEED',
JSON_VALUE(@data,'$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0".state') AS 'JSON_VALUE_SUCCEED',
JSON_QUERY(@data,'$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0".state') AS 'JSON_QUERY_SUCCEED';