在存储过程中多次访问OPENJSON解析的JSON?
以JSON为例:在存储过程中多次访问OPENJSON解析的JSON?,json,sql-server,open-json,Json,Sql Server,Open Json,以JSON为例: { "Name": "Alice", "Relations": [ { "RelationId": 1, "Value": "one" }, { "RelationId": 2, &
{
"Name": "Alice",
"Relations": [
{
"RelationId": 1,
"Value": "one"
},
{
"RelationId": 2,
"Value": "two"
}
]
}
我将此JSON传递给一个存储过程,在其中对其进行解析并插入名称:
-- parse JSON
WITH [source]
AS (SELECT *
FROM
OPENJSON(@json)
WITH
(
[Name] VARCHAR(50),
[Relations] VARCHAR(MAX)
) -- end json WITH
) -- end WITH [source] AS
-- insert Name
INSERT INTO dbo.names
(
[Name]
)
SELECT [s].[Name]
FROM [source] s;
接下来,我想插入关系,因此首先我必须插入OPENJSON
部分:
WITH [relationsSource]
AS (SELECT *
FROM
-- now, here is the problem: the CTE (common table expression)
-- named [source] isn't available anymore
OPENJSON(<how to access [source].[Relations] here?)
WITH
(
[RelationId] INT,
[Value] VARCHAR(50)
) -- end json WITH
) -- end WITH [relationsSource]
这样OPENJSON
就不必再次解析完整的@json
?试试以下方法:
DECLARE @Json NVARCHAR(MAX) = N'
{
"Name": "Alice",
"Relations": [
{
"RelationId": 1,
"Value": "one"
},
{
"RelationId": 2,
"Value": "two"
}
]
}
'
SELECT persons.Id PersonId
, persons.Name
, relations.RelationId
, relations.Value
INTO #JsonToFlatTable
FROM (
-- sub-query to retrieve the root person.Name and the array of relations
SELECT *
, Row_Number() OVER (ORDER BY Name) Id -- Add a fake ID or use some kind of mapping with an existing table.
FROM OPENJSON(@json, N'lax $')
WITH (
[Name] VARCHAR(255) N'lax $.Name'
, Relations nvarchar(MAX) N'$.Relations' AS JSON
)
) persons
-- Use openjson on the subset of relations to retrieve the RelationId and Value
CROSS APPLY OPENJSON(persons.Relations, N'lax $')
WITH(
RelationId INT N'lax $.RelationId'
, Value VARCHAR(255) N'lax $.Value'
) relations
-- Maybe set IDENTITY_INSERT ON
INSERT INTO Person(Id, Name)
SELECT DISTINCT PersonId
, Name
FROM #JsonToFlatTable
-- Maybe set IDENTITY_INSERT OFF
INSERT INTO Relation(PersonId, RelationId, Value)
SELECT PersonId
, RelationId
, Value
FROM #JsonToFlatTable
输出
拟人
名称
关系
价值
1.
爱丽丝
1.
一
1.
爱丽丝
2.
二
你可以试试这样的。
JSON\u VALUE
函数选择“Name”的单个实例。OPENJSON
tvf指定“Relations”对象的路径并提供列定义
declare @json nvarchar(max) = N'
{
"Name": "Alice",
"Relations": [
{
"RelationId": 1,
"Value": "one"
},
{
"RelationId": 2,
"Value": "two"
}
]
}'
select json_value(@json, '$.Name') as [Name], j.*
from openjson(@json, '$.Relations')
with (RelationId int,
[Value] nvarchar(4000)) j;
输出
Name RelationId Value
Alice 1 one
Alice 2 two
谢谢你的详细回复!不幸的是,它告诉我,我可能已经减少了我的问题太多。我需要在两个不同的表中插入数据,因此
Name
进入dbo.names
,如给定,但是对于关系,有第二个表dbo.relations
,并且每一行都需要(,,)。不确定我是否应该问一个新问题或修改我现有的问题):同时,我想知道作为JSON的Relations nvarchar(MAX)N'$.Relations'是否还没有解析这些关系(因为它们作为JSON对象返回),你知道为什么关系需要作为JSON
,JSON作为字符串和JSON作为作为JSON
有什么区别吗?@stefan.at.wpf我已经更新了答案
Name RelationId Value
Alice 1 one
Alice 2 two