Consider this JSON:
{
    "Name": "Alice",
    "Relations": [
        {
            "RelationId": 1,
            "Value": "one"
        },
        {
            "RelationId": 2,
            "Value": "two"
        }
    ]
}
I pass this JSON to a stored procedure where it is parsed and the names are inserted:
-- 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;
Next, I want to insert the relations, so first I have to OPENJSON the [Relations] part:
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]
I know I could do something like OPENJSON(@json, '$Relations'). But this would parse the whole @json again to search for the $Relations path instead of only parsing the previously extracted [source].[Relations].
Is there any solution that allows me using something like
OPENJSON([source].[Relations]) -- pass only the Relations subset of @json
so that OPENJSON doesn't have to parse the complete @json again?
 
     
     
    