温馨提示:本文翻译自stackoverflow.com,查看原文请点击:sql server - TSQL -- Extract JSON values for unknown/dynamic key in sub-object (not an array)
json sql-server tsql

sql server - TSQL-提取子对象(不是数组)中未知/动态键的JSON值

发布于 2020-03-27 15:36:51

我正在使用DataTables,DataTables Editor,JavaScript和MSSQL 2016。

我想在SQL Server中解析此字符串:

{
    "action":"edit",
    "data": { 
                "2019-08-03":{ 
                                "Description":"sdfsafasdfasdf",
                                "FirstFrozenStep":"333"
                             }
            }
}

我不知道如何访问密钥“ 2019-08-03”。这代表主键,或DT_RowId在DataTables Editor中。它是动态的...它可能会改变。

从历史上看,我刚刚将JavaScript中的数据处理为一个FLAT对象,这在SQL Server中更容易解析:

{
     "action":"edit",
     "DT_RowId":"2019-08-03",
     "Description":"sdfsafasdfasdf",
     "FirstFrozenStep":"333"
}

但是,我想知道如何使用json_queryjson_valueopenjson()深入研究上述“动态”键,然后访问其值。

这是我所有失败的尝试:

declare
    @jsonRequest nvarchar(max) = '{"action":"edit","data":{"2019-08-03":{"Description":"sdfsafasdfasdf","FirstFrozenStep":"333"}}}'
    ,@json2 nvarchar(max) = '{"2019-08-03":{"Description":"sdfsafasdfasdf","FirstFrozenStep":"333"}}'
    ,@jsonEASY nvarchar(max) = '{"action":"edit","DT_RowId":"2019-08-03","Description":"sdfsafasdfasdf","FirstFrozenStep":"333"}'


    select
        json_value(@jsonRequest, '$.action') as [action]
        --,json_value(@jsonRequest, '$.data.[0]') as [action]
        --,json_query(@jsonRequest, '$.data[0]')
        --,json_query(@jsonRequest, '$.data.[0]')
        --,json_query(@jsonRequest, '$.data[0].Description')
        --,json_query(@jsonRequest, '$.data.Description')
        --,json_query(@jsonRequest, '$.data.[0].Description')


select
    [Key]
    ,Value
    ,Type
    --,json_query(value, '$')
from
    openjson(@jsonRequest)



SELECT x.[Key], x.[Value]
FROM OPENJSON(@jsonRequest, '$') AS x;

select
    x.[Key]
    ,x.[Value]
    --,json_query(x.value, '$')
    --,(select * from openjson(x.value))
FROM OPENJSON(@jsonRequest, '$') AS x;

SELECT x.[Key], x.[Value]
FROM OPENJSON(@json2, '$') AS x;


    select
        json_value(@jsonEASY, '$.action') as [action]
        ,json_value(@jsonEASY, '$.DT_RowId') as [DT_RowId]
        ,json_value(@jsonEASY, '$.Description') as [Description]

查看更多

查看更多

提问者
raydlevel5
被浏览
116
Shnugo 2020-01-31 16:02

最明确和类型安全的方法可能是:

我用两个动态定义JSON

DECLARE @json NVARCHAR(MAX)=
N'{
    "action":"edit",
    "data": { 
                "2019-08-03":{ 
                                "Description":"sdfsafasdfasdf",
                                "FirstFrozenStep":"333"
                             },
                "2019-08-04":{ 
                                "Description":"blah4",
                                "FirstFrozenStep":"444"
                             }
            }
}';

-查询

SELECT A.[action]
      ,B.[key]
      ,C.*
FROM OPENJSON(@json) WITH([action]  NVARCHAR(100)
                         ,[data]    NVARCHAR(MAX) AS JSON) A
OUTER APPLY OPENJSON(A.[data]) B 
OUTER APPLY OPENJSON(B.[value]) WITH([Description] NVARCHAR(100)
                                     ,FirstFrozenStep INT) C;

结果

action  key         Description     FirstFrozenStep
edit    2019-08-03  sdfsafasdfasdf  333
edit    2019-08-04  blah4           444

简而言之:

  • 第一个OPENJSON()将返回别名下的两个第一级密钥Adata元素返回AS JSON,这使得与稍后进行。
  • 第二OPENJSON()获取A.[data]作为输入,并需要得到在手key,这是你的约会。
  • OPENJSON()现在,第三个B.[value]作为输入。

- WITH子句允许读取隐式旋转和键入的内部元素。

通常:在通用数据容器中,将描述性部分用作内容不是一个好主意这是可能的,并且看起来很聪明,但是最好将日期作为内容放在date-key中。