Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在存储过程中多次访问OPENJSON解析的JSON?_Json_Sql Server_Open Json - Fatal编程技术网

在存储过程中多次访问OPENJSON解析的JSON?

在存储过程中多次访问OPENJSON解析的JSON?,json,sql-server,open-json,Json,Sql Server,Open Json,以JSON为例: { "Name": "Alice", "Relations": [ { "RelationId": 1, "Value": "one" }, { "RelationId": 2, &

以JSON为例:

{
    "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