1

我在表的 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

它不工作

关于我做错了什么的任何建议?

4

3 回答 3

3

只需替换JSON_QUERY为,JSON_VALUE因为您有兴趣获得价值。


JSON_QUERY应该返回一个 JSON 片段并设计用于对象和数组,而不是值。

于 2019-11-13T13:40:13.017 回答
1

您可以尝试另一种可能的方法(更复杂),它解析所有嵌套的 JSON 对象。

桌子:

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中只有一个键"6ee8587f-3b8c-4e5c-89a9-9f04752607f0",则可以使用正确的路径"state" JSON获取值。JSON_VALUE()$.state."6ee8587f-3b8c-4e5c-89a9-9f04752607f0".state

于 2019-11-13T14:10:24.390 回答
1

Salman A 已经给出了答案。只是补充几点。

JSON_VALUE()- 提取标量值

JSON_QUERY()- 从 JSON 字符串中提取对象或数组。

如果您看到语法 , JSON_QUERY ( expression [ , path ] )& ,除了方括号 forJSON_VALUE ( expression , path )之外,两者都或多或少,这意味着可选。这是因为如果需要可以提取整个 JSON 字段。[]pathJSON_QUERY()

在返回类型上,

JSON_VALUE()返回类型的 JSON 片段nvarchar(max)

JSON_QUERY()返回类型的单个文本值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';

在此处检查输出

在此处输入图像描述

于 2019-11-13T14:13:13.987 回答