我正在操作SQL Azure表/数据库中的JSON列,JSON对象形成如下:
{
"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
}
]
}
我想要完成的是在数组“assignations”中找到一个特定元素,然后更新它的一些属性,例如:
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')
当然这个T-SQL无法正常工作,我将不胜感激为您提供帮助
答案 0 :(得分:1)
我找到了一个简单的解决方法"为了解决这个问题,也许这不是最好的解决方案,但我需要一个快速的解决方案,这是有效的。
基本上我将数组转换为T-SQL表,根据需要更新该表上的记录,然后将该表转换为JSON数组,并使用该数组替换原来的数据。
示例代码:
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
答案 1 :(得分:1)
我们必须在工作中做类似的事情,并最终采用与您最终完成的方法类似的方法,尽管我们在读取JSON时直接进行处理,以避免使用临时表或表变量。< / p>
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
最后会产生相同的结果。