我正在使用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_query
,json_value
并openjson()
深入研究上述“动态”键,然后访问其值。
这是我所有失败的尝试:
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]
最明确和类型安全的方法可能是:
我用两个动态键定义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()
将返回别名下的两个第一级密钥A
。该data
元素返回AS JSON
,这使得与稍后进行。OPENJSON()
获取A.[data]
作为输入,并需要得到在手key
,这是你的约会。OPENJSON()
现在,第三个B.[value]
作为输入。- WITH
子句允许读取隐式旋转和键入的内部元素。
通常:在通用数据容器中,将描述性部分用作内容不是一个好主意。这是可能的,并且看起来很聪明,但是最好将日期作为内容放在date
-key中。
我收到此消息:“关键字'with'附近的语法不正确。如果该语句是公用表表达式,xmlnamespaces子句或更改跟踪上下文子句,则前一条语句必须以分号终止。”
@但是raydlevel5不是因为内的OPENJSON声明。这一定是其他...
抱歉,我在附加到具有错误“版本”的数据库上执行时...将报告。谢谢。
我接受您的回答,因为它可以工作,并且您已经说明了我将来可以使用的工具(外部适用)。我完全同意您反对使用通用密钥的声明;但是,您看到的请求是“原始的”,由DataTables Editor构建。由于我可以选择在请求到达SQL之前对其进行操作,因此我可能会继续“平整”数据以使其更易于解析....但是您为我们提供了一种访问通用密钥的方法! !
@ raydlevel5反对内容键的另一个原因是:无论如何,它们都是nvarchar。普通内容的键入方式(例如,日期格式化),您可以使用WITH以类型安全的方式读取它。