更新SQL Server中的嵌套JSON值
我的表中有以下Json:更新SQL Server中的嵌套JSON值,json,sql-server,sql-update,sql-server-2017,Json,Sql Server,Sql Update,Sql Server 2017,我的表中有以下Json: { "filterCriteria":[ { "fieldId":"abc", "filterData":[ { "values":[ { "id":1, "value":"1", "tex
{
"filterCriteria":[
{
"fieldId":"abc",
"filterData":[
{
"values":[
{
"id":1,
"value":"1",
"text":"1"
},
{
"id":2,
"value":"2",
"text":"2"
}
],
"filterType":"equals"
}
]
},
{
"fieldId":"def",
"filterData":[
{
"values":[
{
"id":3,
"value":"3",
"text":"3"
},
{
"id":4,
"value":"4",
"text":"4"
}
],
"filterType":"equals"
}
]
}
]
}
我想根据特定字段Id的索引更新值节点
让我们举个例子:如果我想更新字段id=“abc”
和id=1
的值节点,那么我必须编写以下代码:
DECLARE @JSON nvarchar(max) = Above mentioned JSON
SELECT
JSON_MODIFY(@JSON,'$."filterCriteria"[0].filterData[0].values[0].value', 'Hey');
但是,如果我必须根据某些过滤器上的索引获取进行更新,那么我就不知道如何进行更新。有人能帮我吗?一种可能的方法是解析输入JSON,找到索引并修改JSON。请注意,您需要SQL Server 2017+在
JSON\u MODIFY()
调用中提供一个变量作为path
的值:
JSON:
声明:
SELECT @json = JSON_MODIFY(
@json,
CONCAT('$."filterCriteria"[', id1, '].filterData[', id2, '].values[', id3, '].value'),
'Hey'
)
FROM (
SELECT j1.[key] AS id1, j3.[key] AS id2, j4.[key] AS id3
FROM OPENJSON(@json, '$.filterCriteria') j1
CROSS APPLY OPENJSON(j1.[value], '$') WITH (
fieldId varchar(3) '$.fieldId',
filterData nvarchar(max) '$.filterData' AS JSON
) j2
CROSS APPLY OPENJSON(j2.filterData, '$') j3
CROSS APPLY OPENJSON (j3.[value], '$.values') j4
CROSS APPLY OPENJSON (j3.[value], '$.values') WITH (
id int '$.id'
) j5
WHERE (j2.fieldId = 'abc') AND (j5.id = 1)
) t
SELECT @json
结果(基于您的示例JSON):
谢谢@Zhorov的回复,但我需要更新表中生成的json,filterdata可能有多个值。fieldId=“abc”,而不是id=“abc”我相信这就是你的意思
SELECT @json = JSON_MODIFY(
@json,
CONCAT('$."filterCriteria"[', id1, '].filterData[', id2, '].values[', id3, '].value'),
'Hey'
)
FROM (
SELECT j1.[key] AS id1, j3.[key] AS id2, j4.[key] AS id3
FROM OPENJSON(@json, '$.filterCriteria') j1
CROSS APPLY OPENJSON(j1.[value], '$') WITH (
fieldId varchar(3) '$.fieldId',
filterData nvarchar(max) '$.filterData' AS JSON
) j2
CROSS APPLY OPENJSON(j2.filterData, '$') j3
CROSS APPLY OPENJSON (j3.[value], '$.values') j4
CROSS APPLY OPENJSON (j3.[value], '$.values') WITH (
id int '$.id'
) j5
WHERE (j2.fieldId = 'abc') AND (j5.id = 1)
) t
SELECT @json
{
"filterCriteria":[
{
"fieldId":"abc",
"filterData":[
{
"values":[
{
"id":1,
"value":"Hey",
"text":"1"
},
{
"id":2,
"value":"2",
"text":"2"
}
],
"filterType":"equals"
}
]
},
{
"fieldId":"def",
"filterData":[
{
"values":[
{
"id":3,
"value":"3",
"text":"3"
},
{
"id":4,
"value":"4",
"text":"4"
}
],
"filterType":"equals"
}
]
}
]
}