Example: Updating JSON Data
You can update JSON data using either JSON MERGE clause or ADD clause.
JSON MERGE Clause
You can use the JSON MERGE clause to make a set of changes to a JSON document. The samples in the following section consider airline baggage tracking application and streaming media service application from the CREATE TABLE topic.
Example 7-33 Update existing fields and add a new field to a JSON document
UPDATE BaggageInfo b
JSON MERGE b.bagInfo[0] WITH PATCH {"tagNum" : "18657806255240", "routing" : "MIA/LAX", "lastSeenStation" : "LAX", "bagStatus" : "delivered"}
WHERE ticketNo = 1762344493810 RETURNING b.bagInfo[0].tagNum, b.bagInfo[0].routing, b.bagInfo[0].lastSeenStation, b.bagInfo[0].bagStatus
Explanation: In the query above, you update a passenger's record in the airline baggage tracking application to correct a few inadvertent errors. The JSON MERGE clause compares the content of the patch with the current contents and updates the tagNum
, routing
, and lastSeenStation
fields in the first element of the bagInfo
JSON array. As the bagStatus
field is currently not a part of the first element in the bagInfo
array, the JSON MERGE patch inserts it into the document.
You use the UPDATE statement with a RETURNING clause to display only the updated fields.
{
"tagNum" : "18657806255240",
"routing" : "MIA/LAX",
"lastSeenStation" : "LAX",
"bagStatus" : "delivered"
}
Note:
Here,bagInfo
is an array of JSON documents, which represents the checked bags per passenger. If you don't specify the array element to be updated, the JSON MERGE clause replaces the entire bagInfo
array with the patch content. If there are more than one checked bag per passenger, you can use the JSON MERGE clause iteratively in the same UPDATE statement as follows:UPDATE BaggageInfo b
JSON MERGE b.bagInfo[0] WITH PATCH {"tagNum" : "18657806255111", "routing" : "MIA/LAX", "lastSeenStation" : "LAX", "bagStatus" : "delivered"},
JSON MERGE b.bagInfo[1] WITH PATCH {"tagNum" : "18657806255112", "routing" : "MIA/LAX", "lastSeenStation" : "LAX", "bagStatus" : "delivered"}
WHERE ticketNo = 1762320369957
Example 7-34 Add a new field using its JSON path in the patch
Consider the following passenger's data from the airline baggage tracking application. The nested flightLegs
document does not include the flight number.
{"ticketNo":1882344493810,"fullName":"Joan Smith","gender":"F","contactPhone":"886-324-1064","confNo":"LE6F4Z","bagInfo":[{"flightLegs":{"estimatedArrival":"2019-02-01T11:00:00Z","flightDate":"2019-02-01T06:00:00Z","fltRouteDest":"LAX","fltRouteSrc":"MIA"},"id":"79039899165297","routing":"MIA/LAX","tagNum":"17657806255240"}]}
You can apply a patch to include the flightNo
field into the flightLegs
document as follows:
UPDATE BaggageInfo b
JSON MERGE b.bagInfo[0] WITH PATCH {"flightLegs": {"flightNo":"BM107"}} WHERE ticketNo = 1882344493810 RETURNING *
Explanation: Here, you supply the JSON path of the flightNo
field in the patch expression. The JSON MERGE clause evaluates the JSON path and inserts the flightNo
field into the nested flightLegs
document of the first element of the bagInfo
array.
Output:
{"ticketNo":1882344493810,"fullName":"Joan Smith","gender":"F","contactPhone":"886-324-1064","confNo":"LE6F4Z","bagInfo":[{"flightLegs":{"estimatedArrival":"2019-02-01T11:00:00Z","flightDate":"2019-02-01T06:00:00Z","flightNo":"BM107","fltRouteDest":"LAX","fltRouteSrc":"MIA"},"id":"79039899165297","routing":"MIA/LAX","tagNum":"17657806255240"}]}
Note:
If the nested flightLegs
document does not exist, the JSON MERGE patch creates one.
Example 7-35 Remove field from a JSON document and insert a nested document
UPDATE stream_acct s
JSON MERGE s.acct_data WITH PATCH {"country" : NULL, "recommended" : {"showName1" : "laugh it", "showName2": "Mystery solved", "showName3": "bakesnCooks"}}
WHERE acct_id = 1 RETURNING *
Explanation: In the query above, you use the JSON MERGE clause to update a subscriber record in the streaming media service application. In the patch expression, you supply the country
and recommended
fields. The JSON MERGE patch inserts the new nested recommended
JSON document into the acct_data
JSON document. You indicate the removal of the country
field from the document by supplying a NULL value.
The RETURNING clause fetches the entire updated row.
Output:
{
"acct_id" : 1,
"profile_name" : "AP",
"account_expiry" : "2023-10-18T00:00:00.000000000Z",
"acct_data" : {
"contentStreamed" : [{
"genres" : ["action", "crime", "spanish"],
"numSeasons" : 4,
"seriesInfo" : [{
"episodes" : [{ .... }],
"showId" : 26,
"showName" : "At the Ranch",
"showtype" : "tvseries"
}, {
"genres" : ["comedy", "french"],
"numSeasons" : 2,
"seriesInfo" : [{
"episodes" : [{ .... }],
"showId" : 15,
"showName" : "Bienvenu",
"showtype" : "tvseries"
}],
"firstName" : "Adam",
"lastName" : "Phillips",
"recommended" : {
"showName1" : "laugh it",
"showName2" : "Mystery solved",
"showName3" : "bakesnCooks"
}
}
}
Example 7-36 Update/add a field to a document
Consider following subscriber records from the streaming media service application.
{"acct_id":1,"profile_name":"AP","account_expiry":"2023-10-18T00:00:00.000000000Z","acct_data":{"contentStreamed":[{"genres":["action","crime","spanish"],"numSeasons":4,"showId":26,"showName":"At the Ranch","showtype":"tvseries"},{"genres":["comedy","french"],"numSeasons":2,"showId":15,"showName":"Bienvenu","showtype":"tvseries"}],"firstName":"Adam","lastName":"Phillips"}}
{"acct_id":2,"profile_name":"AW","account_expiry":"2025-12-18T00:00:00.000000000Z","acct_data":{"contentStreamed":{"genres":["comedy","french"],"numSeasons":2,"showId":15,"showName":"Bienvenu","showtype":"tvseries"},"country":"France","firstName":"Adelaide","lastName":"Willard"}}
Example 4a: Use the JSON MERGE clause to update the country field in the acct_data
JSON document for the records above:
UPDATE stream_acct s
JSON MERGE s.acct_data WITH PATCH { "country" : "USA"} WHERE acct_id = 1 RETURNING s.acct_id, s.acct_data.country
UPDATE stream_acct s
JSON MERGE s.acct_data WITH PATCH { "country" : "Italy"} WHERE acct_id = 2 RETURNING s.acct_id, s.acct_data.country
Explanation: In the first UPDATE statement for the acct_id
1, the JSON MERGE clause inserts the country field to the acct_data
JSON document as the field does not exist in the original document. In the second UPDATE statement, the JSON MERGE clause updates the country
field value from France
to Italy
for the subscriber acct_id
2.
Output:
{"acct_id":1,"country":"USA"}
1 row returned
{"acct_id":2,"country":"Italy"}
1 row returned
Example 4b: Update the country
field using path expression.
Consider the original subscriber records from the streaming media service application.
Update the country
field using its path expression for the record with the acct_id
2.
UPDATE stream_acct s
JSON MERGE s.acct_data.country WITH PATCH "Switzerland" where acct_id = 2
{"NumRowsUpdated":1}
Explanation: The UPDATE operation is successful, and the country
field value is replaced with the supplied value. Now update the subscriber record for acct_id
1.
UPDATE stream_acct s
JSON MERGE s.acct_data.country WITH PATCH "USA" where acct_id = 1
{"NumRowsUpdated":0}
In contrast to the UPDATE operation in the Example 4a for acct_id
1, where the country field was successfully inserted, here it is a no-op. When the field that is directly accessed using its path expression does not exist in the target JSON document, the resulting JSON MERGE operation is a no-op.
Example 7-37 Update a JSON NULL field
Consider the following subscriber record from the streaming media service application.
{"acct_id":1,"profile_name":"AP","account_expiry":"2023-10-18T00:00:00.000000000Z","acct_data":null}
Here, the acct_data
is a JSON field with a NULL value. Use the JSON MERGE clause to update the field.
JSON MERGE s.acct_data WITH PATCH {"contentStreamed":{"genres":["comedy","french"],"numSeasons":2,"showId":15,"showName":"Bienvenu","showtype":"tvseries"},"country":NULL,"firstName":"Adam","lastName":"null"} WHERE acct_id = 1 RETURNING *
Explanation: The JSON MERGE patch replaces the NULL value in the acct_data
document with the supplied JSON values from the patch expression. Observe that you supply a JSON NULL value to the country
field. The JSON MERGE patch does not insert this field in the acct_data
document. However, the lastName
field with a string value null
is successfully inserted.
Output:
{"acct_id":1,"profile_name":"AP","account_expiry":"2023-10-18T00:00:00.000000000Z","acct_data":{"contentStreamed":{"genres":["comedy","french"],"numSeasons":2,"showId":15,"showName":"Bienvenu","showtype":"tvseries"},"firstName":"Adam","lastName":"null"}}
ADD clause
You can use ADD clause to update a field in a JSON document. You can add one or more array elements to an existing array using the ADD clause. You can also optionally indicate the position of the new elements to be added in the array.
Example 7-38 Adding a single element to an existing array in JSON data
People
table has one row currently as shown below. For creating the table and inserting data, see Example: Updating Rows.SELECT * FROM People
{
"id" : 0,
"info" : {
"address" : {
"city" : "Santa Cruz",
"phones" : [{
"areacode" : 831,
"kind" : "mobile",
"number" : 5294368
}, {
"areacode" : 650,
"kind" : "mobile",
"number" : 3789021
}, {
"areacode" : 415,
"kind" : "home",
"number" : 6096010
}],
"state" : "CA"
},
"children" : {
"Anna" : {
"age" : 11,
"friends" : ["Anna", "John", "Maria", "Ada", "Aris"],
"school" : "school_1"
},
"Mary" : {
"age" : 8,
"friends" : ["Anna", "Mark", "Ada", "Aris"],
"school" : "school_3"
},
"Ron" : {
"age" : 3,
"friends" : ["Julie", "Ada", "Aris"]
}
},
"firstName" : "John",
"income" : 20000,
"lastName" : "Doe",
"profession" : "surfing instructor"
}
}
phones
array at the beginning of the array.UPDATE People p ADD p.info.address.phones 0
{"areacode":499, "number":33864368, "kind":"mobile" }
WHERE id = 0
SELECT * FROM People
Output:
{
"id" : 0,
"info" : {
"address" : {
"city" : "Santa Cruz",
"phones" : [{
"areacode" : 499,
"kind" : "mobile",
"number" : 33864368
}, {
"areacode" : 831,
"kind" : "mobile",
"number" : 5294368
}, {
"areacode" : 650,
"kind" : "mobile",
"number" : 3789021
}, {
"areacode" : 415,
"kind" : "home",
"number" : 6096010
}],
"state" : "CA"
},
"children" : {
"Anna" : {
"age" : 11,
"friends" : ["Anna", "John", "Maria", "Ada", "Aris"],
"school" : "school_1"
},
"Mary" : {
"age" : 8,
"friends" : ["Anna", "Mark", "Ada", "Aris"],
"school" : "school_3"
},
"Ron" : {
"age" : 3,
"friends" : ["Julie", "Ada", "Aris"]
}
},
"firstName" : "John",
"income" : 20000,
"lastName" : "Doe",
"profession" : "surfing instructor"
}
}
Example 7-39 Adding an array of elements to an existing array in JSON data
When you need to add more than one element of an array to an existing array in JSON data, you need to add the new-elements expressions inside parentheses and optionally add the position expression (if any).
UPDATE People p
ADD p.info.address.phones
0 { "areacode":5, "number":1, "kind":"mobile" },
{ "areacode":6, "number":2, "kind":"mobile" }
WHERE id = 0
Output:
Error handling command UPDATE People p
ADD p.info.address.phones
0 { "areacode":5, "number":1, "kind":"mobile" },
{ "areacode":6, "number":2, "kind":"mobile" }
WHERE id = 0:
Error: at (5, 12) mismatched input '<EOF>' expecting {WHERE, ','}, at line 5:12
rule stack: [parse, statement, update_statement]
This can be corrected using the one of the two different options as shown below:
UPDATE People p
ADD p.info.address.phones
([{ "areacode":1, "number":1, "kind":"mobile" },
{ "areacode":2, "number":2, "kind":"mobile" }
][])
WHERE id = 0
Output:
{
"NumRowsUpdated" : 1
}
1 row returned
UPDATE People p
ADD p.info.address.phones
0 [{ "areacode":3, "number":1, "kind":"mobile" },
{"areacode":4, "number":2, "kind":"mobile" }
]
WHERE id = 0
Output:
{
"NumRowsUpdated" : 1
}
1 row returned
select * from People
Output:
{
"id" : 0,
"info" : {
"address" : {
"city" : "Santa Cruz",
"phones" : [[{
"areacode" : 3,
"kind" : "mobile",
"number" : 1
}, {
"areacode" : 4,
"kind" : "mobile",
"number" : 2
}], {
"areacode" : 499,
"kind" : "mobile",
"number" : 33864368
}, {
"areacode" : 831,
"kind" : "mobile",
"number" : 5294368
}, {
"areacode" : 650,
"kind" : "mobile",
"number" : 3789021
}, {
"areacode" : 415,
"kind" : "home",
"number" : 6096010
}, {
"areacode" : 1,
"kind" : "mobile",
"number" : 1
}, {
"areacode" : 2,
"kind" : "mobile",
"number" : 2
}],
"state" : "CA"
},
"children" : {
"Anna" : {
"age" : 11,
"friends" : ["Anna", "John", "Maria", "Ada", "Aris"],
"school" : "school_1"
},
"Mary" : {
"age" : 8,
"friends" : ["Anna", "Mark", "Ada", "Aris"],
"school" : "school_3"
},
"Ron" : {
"age" : 3,
"friends" : ["Julie", "Ada", "Aris"]
}
},
"firstName" : "John",
"income" : 20000,
"lastName" : "Doe",
"profession" : "surfing instructor"
}
}