1

I am trying to find an effective way to insert a property into an existing json array with out having to do it by index. For example say we had:

DECLARE @json NVARCHAR(MAX);
SET @json = N'
  {
    "objs":[
       {"id":1},
       {"id":2}
     ]
  }
'

How do I add a property to each object in the array? What I would like to do is something like this:

JSON_MODIFY(@json,'$.objs[].parent_id',1);

But this does not work because I did not provide an array index. I am sure there is a simple solution to this, but I could not find one in the docs.

2 Answers 2

4

If you use SQL Server 2017+, you may use JSON_MODIFY() with an expression as path, as is explained in the documentation:

In SQL Server 2017 (14.x) and in Azure SQL Database, you can provide a variable as the value of path.

JSON:

DECLARE @json NVARCHAR(MAX);
SET @json = N'{
   "objs":[
      {
         "id":1
      },
      {
         "id":2
      }
   ]
}';

Statement:

SELECT @json = JSON_MODIFY(@json, CONCAT('$.objs[', [key], '].parent_id'), 1)
FROM OPENJSON(@json, '$.objs')

Result:

{
   "objs":[
      {
         "id":1,
         "parent_id":1
      },
      {
         "id":2,
         "parent_id":1
      }
   ]
}
Sign up to request clarification or add additional context in comments.

2 Comments

This is exactly what I was looking for Thanks!
Link to JSON_MODIFY() in the docs learn.microsoft.com/en-us/sql/t-sql/functions/…
1

I suppose you can use OPENJSON and FOR JSON to shred and combine the JSON:

DECLARE @json NVARCHAR(MAX);

SET @json = N'{
  "objs": [{
    "id": 1
  }, {
    "id": 2
  }]
}';

SELECT id, 1 AS parent_id
FROM OPENJSON(@json, '$.objs')
WITH (
    id INT '$.id'
)
FOR JSON PATH, ROOT('objs')

Result:

{
  "objs": [{
    "id": 1,
    "parent_id": 1
  }, {
    "id": 2,
    "parent_id": 1
  }]
}

2 Comments

Yeah this is what I was bout to try. I was just hoping for a better way. Thanks!
JSON_MODIFY wont help since it modifies one property at a time. This solution should be OK unless you don't know the name of keys in child object in advance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.