鉴于json就是这样......
{"setting1":"A","setting2":"B","setting3":"C"}
我希望看到像...的结果
+----------+-------+
| name | value |
+----------+-------+
| setting1 | A |
| setting2 | B |
| setting3 | C |
+----------+-------+
我的努力是试图找出如何提取密钥的名称(即"设置1","设置2"," setting3"等等。)
我可以执行类似以下查询的操作,但我不知道会有多少设置以及它们的名称,所以我想要更有活力的内容。
SELECT
B.name,
B.value
FROM OPENJSON(@json) WITH
(
setting1 varchar(50) '$.setting1',
setting2 varchar(50) '$.setting2',
setting3 varchar(50) '$.setting3'
) A
CROSS APPLY
(
VALUES
('setting1', A.setting1),
('setting2', A.setting2),
('setting3', A.setting3)
) B (name, value)
使用XML,我可以做这样简单的事情:
DECLARE @xml XML = '<settings><setting1>A</setting1><setting2>B</setting2><setting3>C</setting3></settings>'
SELECT
A.setting.value('local-name(.)', 'VARCHAR(50)') name,
A.setting.value('.', 'VARCHAR(50)') value
FROM @xml.nodes('settings/*') A (setting)
用SQL Server的json功能做任何类似的事情吗?
答案 0 :(得分:2)
Aaron Bertrand在attribute directives
中写过关于json键值的文章SELECT x.[Key], x.[Value]
FROM OPENJSON(@Json, '$') AS x;
返回
Key Value
------------------
setting1 A
setting2 B
setting3 C
答案 1 :(得分:0)
使用表格的选项
ID Name Value
1 setting1 A
1 setting2 B
1 setting3 C
<强>返回强>
Declare @String varchar(max) = '{"setting1":"A","setting2":"B","setting3":"C"}'
Select C.*
From (values (try_convert(xml,replace(replace(replace(replace(replace(@String,'"',''),'{','<row '),'}','"/>'),':','="'),',','" '))) ) A (XMLData)
Cross Apply (
Select Name = attr.value('local-name(.)','varchar(100)')
,Value = attr.value('.','varchar(max)')
From A.XMLData.nodes('/row') as C1(r)
Cross Apply C1.r.nodes('./@*') as C2(attr)
) C
使用字符串变量的选项
Name Value
setting1 A
setting2 B
setting3 C
<强>返回强>
{{1}}
答案 2 :(得分:0)
如果您对TVF开放。
以下内容需要我的Extract UDF。创建此函数是因为我厌倦了提取字符串(patindex,charindex,left,right等)。它是一个修改的计数解析,它接受两个非类似的分隔符。
示例强>
Declare @YourTable table (ID int,JSON_String varchar(max))
Insert Into @YourTable values
(1,'{"setting1":{"global":"A","type":"1"},"setting2":{"global":"B","type":"1"},"setting3":{"global":"C","type":"1"}} ')
Select A.ID
,B.Setting
,C.*
From @YourTable A
Cross Apply (
Select Setting = replace(replace(B1.RetVal,'"',''),'{','')
,B2.RetVal
From [dbo].[udf-Str-Extract](A.JSON_String,',',':{') B1
Join [dbo].[udf-Str-Extract](A.JSON_String,':{','}') B2
on B1.RetSeq=B2.RetSeq
) B
Cross Apply (
Select Name = C1.RetVal
,Value = C2.RetVal
From [dbo].[udf-Str-Extract](','+B.RetVal,',"','":') C1
Join [dbo].[udf-Str-Extract](B.RetVal+',',':"','",') C2
on C1.RetSeq=C2.RetSeq
) C
<强>返回强>
ID Setting Name Value
1 setting1 global A
1 setting1 type 1
1 setting2 global B
1 setting2 type 1
1 setting3 global C
1 setting3 type 1
感兴趣的UDF
CREATE FUNCTION [dbo].[udf-Str-Extract] (@String varchar(max),@Delimiter1 varchar(100),@Delimiter2 varchar(100))
Returns Table
As
Return (
with cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cte2(N) As (Select Top (IsNull(DataLength(@String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 N1,cte1 N2,cte1 N3,cte1 N4,cte1 N5,cte1 N6) A ),
cte3(N) As (Select 1 Union All Select t.N+DataLength(@Delimiter1) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter1)) = @Delimiter1),
cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter1,@String,s.N),0)-S.N,8000) From cte3 S)
Select RetSeq = Row_Number() over (Order By N)
,RetPos = N
,RetVal = left(RetVal,charindex(@Delimiter2,RetVal)-1)
From (
Select *,RetVal = Substring(@String, N, L)
From cte4
) A
Where charindex(@Delimiter2,RetVal)>1
)
/*
Max Length of String 1MM characters
Declare @String varchar(max) = 'Dear [[FirstName]] [[LastName]], ...'
Select * From [dbo].[udf-Str-Extract] (@String,'[[',']]')
*/