SQL JSON 更新
SQL JSON update
如果我有这个JSON
{
"hello1": "1",
"hello2": "2"
}
我想从这个 JSON
更新它
{
"hello2": "3"
}
我想要的结果是
{
"hello1": "1",
"hello2": "3"
}
有没有一种方法可以做到这一点而无需遍历 SQL 中的每个字段?
我目前的尝试是像这样手动更新每个值:
SET @OldJSON = JSON_MODIFY(
@OldJSON,
'$.hello1',
ISNULL(JSON_VALUE(@JSON,'$.hello1'), JSON_VALUE(@OldJSON,'$.hello1'))
)
获得预期结果的可能选项是:
JSON_MODIFY()
和 SELECT
语句
JSON_MODIFY()
和动态语句
JSON_MODIFY()
和 SELECT
语句:
如 documentation 中所述,在 SQL Server 2017 (14.x) 和 Azure SQL 数据库中,您可以提供变量(或表达式在这种情况下)作为路径的值。
因此,您可以轻松地为每个新 key/value
对构建路径。
DECLARE @old varchar(1000) = '{"hello1":"1","hello2":"2","hello3":"3"}'
DECLARE @new varchar(1000) = '{"hello2":"a","hello3":"b"}'
SELECT @old = JSON_MODIFY(
@old,
CONCAT('$."', n.[key], '"'),
COALESCE(n.[value], o.[value])
)
FROM OPENJSON(@old) o
JOIN OPENJSON(@new) n ON n.[key] = o.[key]
JSON_MODIFY()
和动态语句:
场景几乎相同,但每次更新都在单独的语句中,动态生成:
DECLARE @old varchar(1000) = '{"hello1":"1","hello2":"2","hello3":"3"}'
DECLARE @new varchar(1000) = '{"hello2":"a","hello3":"b"}'
DECLARE @stm nvarchar(max)
SELECT @stm = STRING_AGG(
CONCAT(
'SELECT @old = JSON_MODIFY(@old, ''$."', n.[key], '"'', ''',
COALESCE(n.[value], o.[value]), ''')'
),
'; '
)
FROM OPENJSON(@old) o
JOIN OPENJSON(@new) n ON n.[key] = o.[key]
DECLARE @err int
EXEC @err = sp_executesql @stm, N'@old varchar(1000) OUTPUT', @old OUTPUT
IF @err = 0 PRINT 'Success' ELSE PRINT 'Error'
结果:
两种方法 return 以下 JSON:
{"hello1":"1","hello2":"a","hello3":"b"}
添加新的 key\value
对:
如果新的 JSON 内容包含新的 key\value
对,只需使用 FULL JOIN
:
DECLARE @old varchar(1000) = '{"hello1":"1","hello2":"2","hello3":"3"}'
DECLARE @new varchar(1000) = '{"hello2":"a","hello4":"b"}'
SELECT @old = JSON_MODIFY(
@old,
CONCAT('$."', n.[key], '"'),
COALESCE(n.[value], o.[value])
)
FROM OPENJSON(@old) o
FULL JOIN OPENJSON(@new) n ON n.[key] = o.[key]
如果我有这个JSON
{
"hello1": "1",
"hello2": "2"
}
我想从这个 JSON
更新它{
"hello2": "3"
}
我想要的结果是
{
"hello1": "1",
"hello2": "3"
}
有没有一种方法可以做到这一点而无需遍历 SQL 中的每个字段?
我目前的尝试是像这样手动更新每个值:
SET @OldJSON = JSON_MODIFY(
@OldJSON,
'$.hello1',
ISNULL(JSON_VALUE(@JSON,'$.hello1'), JSON_VALUE(@OldJSON,'$.hello1'))
)
获得预期结果的可能选项是:
JSON_MODIFY()
和SELECT
语句JSON_MODIFY()
和动态语句
JSON_MODIFY()
和 SELECT
语句:
如 documentation 中所述,在 SQL Server 2017 (14.x) 和 Azure SQL 数据库中,您可以提供变量(或表达式在这种情况下)作为路径的值。
因此,您可以轻松地为每个新 key/value
对构建路径。
DECLARE @old varchar(1000) = '{"hello1":"1","hello2":"2","hello3":"3"}'
DECLARE @new varchar(1000) = '{"hello2":"a","hello3":"b"}'
SELECT @old = JSON_MODIFY(
@old,
CONCAT('$."', n.[key], '"'),
COALESCE(n.[value], o.[value])
)
FROM OPENJSON(@old) o
JOIN OPENJSON(@new) n ON n.[key] = o.[key]
JSON_MODIFY()
和动态语句:
场景几乎相同,但每次更新都在单独的语句中,动态生成:
DECLARE @old varchar(1000) = '{"hello1":"1","hello2":"2","hello3":"3"}'
DECLARE @new varchar(1000) = '{"hello2":"a","hello3":"b"}'
DECLARE @stm nvarchar(max)
SELECT @stm = STRING_AGG(
CONCAT(
'SELECT @old = JSON_MODIFY(@old, ''$."', n.[key], '"'', ''',
COALESCE(n.[value], o.[value]), ''')'
),
'; '
)
FROM OPENJSON(@old) o
JOIN OPENJSON(@new) n ON n.[key] = o.[key]
DECLARE @err int
EXEC @err = sp_executesql @stm, N'@old varchar(1000) OUTPUT', @old OUTPUT
IF @err = 0 PRINT 'Success' ELSE PRINT 'Error'
结果:
两种方法 return 以下 JSON:
{"hello1":"1","hello2":"a","hello3":"b"}
添加新的 key\value
对:
如果新的 JSON 内容包含新的 key\value
对,只需使用 FULL JOIN
:
DECLARE @old varchar(1000) = '{"hello1":"1","hello2":"2","hello3":"3"}'
DECLARE @new varchar(1000) = '{"hello2":"a","hello4":"b"}'
SELECT @old = JSON_MODIFY(
@old,
CONCAT('$."', n.[key], '"'),
COALESCE(n.[value], o.[value])
)
FROM OPENJSON(@old) o
FULL JOIN OPENJSON(@new) n ON n.[key] = o.[key]