I'm manipulating a JSON column in a SQL Azure table/database, the JSON object is formed like this:
{
"statusId": "5A5BC717-F33A-42A5-8E48-99531C30EC87",
"creationDateTime": "",
"assignations": [
{
"userId": "CA3B0589-B558-4FCC-93A6-560754D324FC",
"dateTime": "",
"isCurrentAssigned": false
},
{
"userId": "CA3B0589-B558-4FCC-93A6-560754D325E8",
"dateTime": "",
"isCurrentAssigned": false
},
{
"userId": "CA3B0589-B558-4FCC-93A6-560754D347N",
"dateTime": "",
"isCurrentAssigned": true
}
]
}
What I want to accomplish is to find a specific element inside the array "assignations" and then update some of its properties, just something like:
UPDATE MyTable
SET JsonData = JSON_MODIFY(JsonData, '$.assignations.isCurrentAssigned', CONVERT(BIT, 0))
FROM MyDb
WHERE JSON_VALUE(JsonData, '$.assignations.isCurrentAssigned') = CONVERT(BIT, 1) AND
JSON_VALUE(JsonData, '$.assignations.userId') = CONVERT(UNIQUEIDENTIFIER, 'CA3B0589-B558-4FCC-93A6-560754D347N')
Of course this T-SQL is not working, I will appreciate any help on this
To change the value of an object in an array:Call the findIndex() method to get the index of the specific object. Access the array at the index and change the property's value using dot notation. The value of the object in the array will get updated in place.
Array value of a JSON object can be modified. It can be simply done by modifying the value present at a given index. Note: If value is modified at an index which is out of the array size, then the new modification will not replace anything in the original information but rather will be an add-on.
Approach 1: First convert the JSON string to the JavaScript object using JSON. Parse() method and then take out the values of the object and push them into the array using push() method.
JavaScript offers two ways to update the object, using map () and findIndex (). This built-in array method, provided by JavaScript, iterates over the original array and creates the new array, completing the elements based on the specified conditions. Instead of an arrow function, you can also pass the callback function.
How to modify an array value of a JSON object in JavaScript? Modifying an array is just like modifying an object when that array is inside the object. The normal general principles will apply here. In the following example, Initially in the ' companies ' array, the first element is ' Tesla'.
So let's take a look at how we can add objects to an already existing array. To add an object at the first position, use Array.unshift. To add an object at the last position, use Array.push. To add an object in the middle, use Array.splice. This function is very handy as it can also remove items.
In addition, I use a series of variables to change a certain element, the process is more cumbersome, there may be a better way, but you could refer to this method first: The general idea is to manually add an index to the array, then change the array element corresponding to the specified index, empty the previous array, and add the new element.
I've found a "simple workaround" to handle this, maybe it is not the best solution but I need a quick solution and this is working.
Basically I convert the array to a T-SQL Table, update the records on that table as desired, then convert that table to a JSON Array and with that array I replace the original one.
Sample code:
DECLARE @SomeJSON NVARCHAR(MAX) =
'{
"statusId": "5A5BC717-F33A-42A5-8E48-99531C30EC87",
"creationDateTime": "abc",
"assignations": [
{
"userId": "5A5BC717-F33A-42A5-8E48-99531C30EC87",
"creationDateTime": "",
"isCurrentAssigned": false
},
{
"userId": "5A5BC717-F33A-42A5-8E48-99531C30EC87",
"creationDateTime": "",
"isCurrentAssigned": false
},
{
"userId": "5A5BC717-F33A-42A5-8E48-99531C30EC87",
"creationDateTime": "",
"isCurrentAssigned": true
}
]
}'
DECLARE @TblAssignations TABLE
(
userId UNIQUEIDENTIFIER NULL,
creationDateTime DATETIME NULL,
isCurrentAssigned BIT NULL
)
INSERT INTO @TblAssignations
SELECT *
FROM OPENJSON(@SomeJSON, '$.assignations')
WITH(userId UNIQUEIDENTIFIER, creationDateTime DATETIME, isCurrentAssigned BIT)
UPDATE @TblAssignations
SET isCurrentAssigned = 0
WHERE userId = '5A5BC717-F33A-42A5-8E48-99531C30EC87' AND
isCurrentAssigned = 1
INSERT INTO @TblAssignations
VALUES
(
'5A5BC717-F33A-42A5-8E48-99531C30EC87',
'',
1
)
DECLARE @NewParentAssignations NVARCHAR(MAX) = (SELECT * FROM @TblAssignations FOR JSON PATH)
SET @SomeJSON = JSON_MODIFY(@SomeJSON, '$.assignations', JSON_QUERY(@NewParentAssignations))
SELECT @SomeJSON
We have to do something similar at work, and ended up with a similar approach to the one you ended up with, although we do the processing directly while reading the JSON, to avoid using a temp table or a table var.
DECLARE @SomeJSON NVARCHAR(MAX) =
'{
"statusId": "5A5BC717-F33A-42A5-8E48-99531C30EC87",
"creationDateTime": "abc",
"assignations": [
{
"userId": "5A5BC717-F33A-42A5-8E48-99531C30EC87",
"creationDateTime": "",
"isCurrentAssigned": false
},
{
"userId": "5A5BC717-F33A-42A5-8E48-99531C30EC87",
"creationDateTime": "",
"isCurrentAssigned": false
},
{
"userId": "5A5BC717-F33A-42A5-8E48-99531C30EC87",
"creationDateTime": "",
"isCurrentAssigned": true
}
]
}'
DECLARE @NewParentAssignations NVARCHAR(MAX) = (
SELECT *
FROM (
SELECT --the update is done with the CASE clause
userId,
creationDateTime,
CASE WHEN userId = '5A5BC717-F33A-42A5-8E48-99531C30EC87' AND isCurrentAssigned = 1
THEN CAST (0 AS BIT)
ELSE isCurrentAssigned
END AS isCurrentAssigned
FROM OPENJSON(@SomeJSON, '$.assignations')
WITH(userId UNIQUEIDENTIFIER, creationDateTime DATETIME, isCurrentAssigned BIT)
UNION ALL -- the insert is done using UNION ALL
SELECT '5A5BC717-F33A-42A5-8E48-99531C30EC87' AS userId, '' AS creationDateTime, CAST (1 AS BIT) AS isCurrentAssigned
) Result
FOR JSON PATH
)
SET @SomeJSON = JSON_MODIFY(@SomeJSON, '$.assignations', JSON_QUERY(@NewParentAssignations))
SELECT @SomeJSON
At the end this yields the same result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With