json - How to JSON_MODIFY on Array of Array? -
my strucutre this
declare @layout nvarchar(max) = n' { "sections": [ { "sectionname":"section1", "sectionorder":1, "renders":[ { "rendername":"render1", "renderorder":1, "fields":[ { "fieldname":"field1", "fielddata":"data1" }, { "fieldname":"field2", "fielddata":"data2" } ] }, { "rendername":"render2", "renderorder":2, "fields":[ { "fieldname":"field1", "fielddata":"data1" }, { "fieldname":"field2", "fielddata":"data2" } ] } ] }, { "sectionname":"section2", "sectionorder":2, "renders":[ { "rendername":"render1", "renderorder":1, "fields":[ { "fieldname":"field1", "fielddata":"data1" } ] }, { "rendername":"render2", "renderorder":2, "fields":[ { "fieldname":"field1", "fielddata":"data1" }, { "fieldname":"field2", "fielddata":"data2" } ] } ] } ] } ' what do this:
update fielddata = 'dataupdated' fieldname = 'field2' , rendername = 'render' , sectionname = 'section1' how using json_modify?
i can data using following query: select sectionname, sectionorder, rendername, renderorder, fieldname, fielddata ( select sectionname, sectionorder, rendername, renderorder, fields ( select sectionname, sectionorder, renders openjson(@layout,'$.sections') ( sectionname nvarchar(max) '$.sectionname', sectionorder nvarchar(max) '$.sectionorder', renders nvarchar(max) '$.renders' json ) ) sections cross apply openjson(renders,'$') ( rendername nvarchar(max) '$.rendername', renderorder nvarchar(max) '$.renderorder', fields nvarchar(max) '$.fields' json ) ) renders cross apply openjson(fields,'$') ( fieldname nvarchar(max) '$.fieldname', fielddata nvarchar(max) '$.fielddata' )
this not straightforward 1 might hope. surprised there seems no simple way query full path of item in json structure.
json_modify can accept array indicies when targetting member of array, of work here goes generating indexes each nested array member. appears [key] column can generated when using openjson without with clause, couldn't reuse query.
additionally, json_modify accept string literal json path, update has carried out using dynamic sql.
(please note solution assumes want update specific rendername e.g. 'render1' - question unclear on point.)
declare @path nvarchar(2048) select @path = formatmessage('set @layout = json_modify(@layout, ''$.sections[%s].renders[%s].fields[%s].fielddata'', @newvalue)' ,sectionindex, renderindex, [key]) ( select sectionindex, sectionname, b.[key] renderindex, b.[value] bvalue, json_value([value], '$.rendername') rendername (select [key] sectionindex, [value] avalue, json_value([value], '$.sectionname') sectionname openjson(@layout, '$.sections') ) sections cross apply openjson(sections.avalue, '$.renders') b ) renders cross apply openjson(renders.bvalue,'$.fields' ) d json_value([value], '$.fieldname') = 'field2' , rendername = 'render1' , sectionname = 'section1' -- execute update; has happen in dynamic sql because json_modify path has literal value, , cannot variable exec sp_executesql @path, n'@layout nvarchar(max) output, @newvalue nvarchar(max)', @layout = @layout output, @newvalue = 'dateupdated' --check results select sectionindex, sectionname, renderindex, rendername, [key] fieldindex, json_value([value], '$.fieldname') fieldname, json_value([value], '$.fielddata') fieldname ( select sectionindex, sectionname, b.[key] renderindex, b.[value] bvalue, json_value([value], '$.rendername') rendername (select [key] sectionindex, [value] avalue, json_value([value], '$.sectionname') sectionname openjson(@layout, '$.sections') ) sections cross apply openjson(sections.avalue, '$.renders') b ) renders cross apply openjson(renders.bvalue,'$.fields' ) d
Comments
Post a Comment