本節中的函數會修改 JSON 值並傳回結果。
JSON_ARRAY_APPEND(
json_doc
,path
,val
[,path
,val
] ...)將值附加到 JSON 文件中指定陣列的末尾,並傳回結果。如果任何引數為
NULL
,則傳回NULL
。如果json_doc
引數不是有效的 JSON 文件,或任何path
引數不是有效的路徑表達式,或包含*
或**
萬用字元,則會發生錯誤。路徑值對會從左至右評估。評估一對所產生的文件會成為新值,並根據新值評估下一對。
如果路徑選取純量值或物件值,則該值會自動包裝在陣列中,並且新值會新增至該陣列。路徑未識別 JSON 文件中任何值的配對將會被忽略。
mysql> SET @j = '["a", ["b", "c"], "d"]'; mysql> SELECT JSON_ARRAY_APPEND(@j, '$[1]', 1); +----------------------------------+ | JSON_ARRAY_APPEND(@j, '$[1]', 1) | +----------------------------------+ | ["a", ["b", "c", 1], "d"] | +----------------------------------+ mysql> SELECT JSON_ARRAY_APPEND(@j, '$[0]', 2); +----------------------------------+ | JSON_ARRAY_APPEND(@j, '$[0]', 2) | +----------------------------------+ | [["a", 2], ["b", "c"], "d"] | +----------------------------------+ mysql> SELECT JSON_ARRAY_APPEND(@j, '$[1][0]', 3); +-------------------------------------+ | JSON_ARRAY_APPEND(@j, '$[1][0]', 3) | +-------------------------------------+ | ["a", [["b", 3], "c"], "d"] | +-------------------------------------+ mysql> SET @j = '{"a": 1, "b": [2, 3], "c": 4}'; mysql> SELECT JSON_ARRAY_APPEND(@j, '$.b', 'x'); +------------------------------------+ | JSON_ARRAY_APPEND(@j, '$.b', 'x') | +------------------------------------+ | {"a": 1, "b": [2, 3, "x"], "c": 4} | +------------------------------------+ mysql> SELECT JSON_ARRAY_APPEND(@j, '$.c', 'y'); +--------------------------------------+ | JSON_ARRAY_APPEND(@j, '$.c', 'y') | +--------------------------------------+ | {"a": 1, "b": [2, 3], "c": [4, "y"]} | +--------------------------------------+ mysql> SET @j = '{"a": 1}'; mysql> SELECT JSON_ARRAY_APPEND(@j, '$', 'z'); +---------------------------------+ | JSON_ARRAY_APPEND(@j, '$', 'z') | +---------------------------------+ | [{"a": 1}, "z"] | +---------------------------------+
JSON_ARRAY_INSERT(
json_doc
,path
,val
[,path
,val
] ...)更新 JSON 文件,插入到文件中的陣列,並傳回修改後的文件。如果任何引數為
NULL
,則傳回NULL
。如果json_doc
引數不是有效的 JSON 文件,或任何path
引數不是有效的路徑表達式,或包含*
或**
萬用字元,或未以陣列元素識別碼結尾,則會發生錯誤。路徑值對會從左至右評估。評估一對所產生的文件會成為新值,並根據新值評估下一對。
路徑未識別 JSON 文件中任何陣列的配對將會被忽略。如果路徑識別陣列元素,則對應的值會插入到該元素位置,將任何後續的值向右移動。如果路徑識別陣列末尾之後的陣列位置,則值會插入到陣列的末尾。
mysql> SET @j = '["a", {"b": [1, 2]}, [3, 4]]'; mysql> SELECT JSON_ARRAY_INSERT(@j, '$[1]', 'x'); +------------------------------------+ | JSON_ARRAY_INSERT(@j, '$[1]', 'x') | +------------------------------------+ | ["a", "x", {"b": [1, 2]}, [3, 4]] | +------------------------------------+ mysql> SELECT JSON_ARRAY_INSERT(@j, '$[100]', 'x'); +--------------------------------------+ | JSON_ARRAY_INSERT(@j, '$[100]', 'x') | +--------------------------------------+ | ["a", {"b": [1, 2]}, [3, 4], "x"] | +--------------------------------------+ mysql> SELECT JSON_ARRAY_INSERT(@j, '$[1].b[0]', 'x'); +-----------------------------------------+ | JSON_ARRAY_INSERT(@j, '$[1].b[0]', 'x') | +-----------------------------------------+ | ["a", {"b": ["x", 1, 2]}, [3, 4]] | +-----------------------------------------+ mysql> SELECT JSON_ARRAY_INSERT(@j, '$[2][1]', 'y'); +---------------------------------------+ | JSON_ARRAY_INSERT(@j, '$[2][1]', 'y') | +---------------------------------------+ | ["a", {"b": [1, 2]}, [3, "y", 4]] | +---------------------------------------+ mysql> SELECT JSON_ARRAY_INSERT(@j, '$[0]', 'x', '$[2][1]', 'y'); +----------------------------------------------------+ | JSON_ARRAY_INSERT(@j, '$[0]', 'x', '$[2][1]', 'y') | +----------------------------------------------------+ | ["x", "a", {"b": [1, 2]}, [3, 4]] | +----------------------------------------------------+
先前的修改會影響陣列中後續元素的位置,因此在同一個
JSON_ARRAY_INSERT()
呼叫中的後續路徑應將此納入考量。在最後一個範例中,第二個路徑不會插入任何內容,因為在第一次插入之後,該路徑不再比對任何內容。JSON_INSERT(
json_doc
,path
,val
[,path
,val
] ...)將資料插入 JSON 文件中並傳回結果。如果任何引數為
NULL
,則傳回NULL
。如果json_doc
引數不是有效的 JSON 文件,或任何path
引數不是有效的路徑表達式,或包含*
或**
萬用字元,則會發生錯誤。路徑值對會從左至右評估。評估一對所產生的文件會成為新值,並根據新值評估下一對。
文件中現有路徑的路徑值對會被忽略,並且不會覆寫現有的文件值。如果路徑識別下列其中一種值類型,則文件中不存在的路徑的路徑值對會將值新增至文件中
現有物件中不存在的成員。成員會新增至物件,並與新值建立關聯。
現有陣列末尾之後的位置。陣列會擴充新值。如果現有值不是陣列,則會自動包裝為陣列,然後使用新值擴充。
否則,文件中不存在的路徑的路徑值對將會被忽略,並且沒有任何作用。
如需比較
JSON_INSERT()
、JSON_REPLACE()
和JSON_SET()
,請參閱JSON_SET()
的討論。mysql> SET @j = '{ "a": 1, "b": [2, 3]}'; mysql> SELECT JSON_INSERT(@j, '$.a', 10, '$.c', '[true, false]'); +----------------------------------------------------+ | JSON_INSERT(@j, '$.a', 10, '$.c', '[true, false]') | +----------------------------------------------------+ | {"a": 1, "b": [2, 3], "c": "[true, false]"} | +----------------------------------------------------+
結果中列出的第三個和最後一個值是加引號的字串,而不是像第二個值一樣的陣列 (在輸出中未加引號);不會執行將值轉換為 JSON 類型的作業。若要將陣列以陣列形式插入,您必須明確執行此類轉換,如此處所示
mysql> SELECT JSON_INSERT(@j, '$.a', 10, '$.c', CAST('[true, false]' AS JSON)); +------------------------------------------------------------------+ | JSON_INSERT(@j, '$.a', 10, '$.c', CAST('[true, false]' AS JSON)) | +------------------------------------------------------------------+ | {"a": 1, "b": [2, 3], "c": [true, false]} | +------------------------------------------------------------------+ 1 row in set (0.00 sec)
JSON_MERGE(
json_doc
,json_doc
[,json_doc
] ...)已淘汰的
JSON_MERGE_PRESERVE()
同義詞。JSON_MERGE_PATCH(
json_doc
,json_doc
[,json_doc
] ...)執行符合 RFC 7396 標準的兩個或多個 JSON 文件合併,並傳回合併結果,但不保留具有重複鍵的成員。如果傳遞給此函數的參數中至少有一個文件無效,則會引發錯誤。
注意有關此函數與
JSON_MERGE_PRESERVE()
之間的差異說明和範例,請參閱JSON_MERGE_PATCH() 與 JSON_MERGE_PRESERVE() 的比較。JSON_MERGE_PATCH()
執行合併的方式如下如果第一個參數不是物件,則合併的結果與將空物件與第二個參數合併的結果相同。
如果第二個參數不是物件,則合併的結果是第二個參數。
如果兩個參數都是物件,則合併的結果是一個具有以下成員的物件:
第一個物件的所有成員,這些成員在第二個物件中沒有對應的相同鍵的成員。
第二個物件的所有成員,這些成員在第一個物件中沒有對應的鍵,且其值不是 JSON
null
字面值。在第一個和第二個物件中都存在鍵的所有成員,且其在第二個物件中的值不是 JSON
null
字面值。這些成員的值是將第一個物件中的值與第二個物件中的值遞迴合併的結果。
有關其他資訊,請參閱JSON 值的正規化、合併和自動包裝。
mysql> SELECT JSON_MERGE_PATCH('[1, 2]', '[true, false]'); +---------------------------------------------+ | JSON_MERGE_PATCH('[1, 2]', '[true, false]') | +---------------------------------------------+ | [true, false] | +---------------------------------------------+ mysql> SELECT JSON_MERGE_PATCH('{"name": "x"}', '{"id": 47}'); +-------------------------------------------------+ | JSON_MERGE_PATCH('{"name": "x"}', '{"id": 47}') | +-------------------------------------------------+ | {"id": 47, "name": "x"} | +-------------------------------------------------+ mysql> SELECT JSON_MERGE_PATCH('1', 'true'); +-------------------------------+ | JSON_MERGE_PATCH('1', 'true') | +-------------------------------+ | true | +-------------------------------+ mysql> SELECT JSON_MERGE_PATCH('[1, 2]', '{"id": 47}'); +------------------------------------------+ | JSON_MERGE_PATCH('[1, 2]', '{"id": 47}') | +------------------------------------------+ | {"id": 47} | +------------------------------------------+ mysql> SELECT JSON_MERGE_PATCH('{ "a": 1, "b":2 }', > '{ "a": 3, "c":4 }'); +-----------------------------------------------------------+ | JSON_MERGE_PATCH('{ "a": 1, "b":2 }','{ "a": 3, "c":4 }') | +-----------------------------------------------------------+ | {"a": 3, "b": 2, "c": 4} | +-----------------------------------------------------------+ mysql> SELECT JSON_MERGE_PATCH('{ "a": 1, "b":2 }','{ "a": 3, "c":4 }', > '{ "a": 5, "d":6 }'); +-------------------------------------------------------------------------------+ | JSON_MERGE_PATCH('{ "a": 1, "b":2 }','{ "a": 3, "c":4 }','{ "a": 5, "d":6 }') | +-------------------------------------------------------------------------------+ | {"a": 5, "b": 2, "c": 4, "d": 6} | +-------------------------------------------------------------------------------+
您可以使用此函數來移除成員,方法是在第二個參數中將相同成員的值指定為
null
,如下所示:mysql> SELECT JSON_MERGE_PATCH('{"a":1, "b":2}', '{"b":null}'); +--------------------------------------------------+ | JSON_MERGE_PATCH('{"a":1, "b":2}', '{"b":null}') | +--------------------------------------------------+ | {"a": 1} | +--------------------------------------------------+
此範例顯示該函數以遞迴方式運作;也就是說,成員的值不僅限於純量,還可以是 JSON 文件本身。
mysql> SELECT JSON_MERGE_PATCH('{"a":{"x":1}}', '{"a":{"y":2}}'); +----------------------------------------------------+ | JSON_MERGE_PATCH('{"a":{"x":1}}', '{"a":{"y":2}}') | +----------------------------------------------------+ | {"a": {"x": 1, "y": 2}} | +----------------------------------------------------+
JSON_MERGE_PATCH() 與 JSON_MERGE_PRESERVE() 的比較。
JSON_MERGE_PATCH()
的行為與JSON_MERGE_PRESERVE()
相同,但有以下兩個例外:JSON_MERGE_PATCH()
會移除第一個物件中在第二個物件中具有匹配鍵的任何成員,前提是第二個物件中與該鍵關聯的值不是 JSONnull
。如果第二個物件具有與第一個物件中成員匹配的鍵的成員,則
JSON_MERGE_PATCH()
會取代第一個物件中的值,而JSON_MERGE_PRESERVE()
則會將第二個值附加到第一個值。
此範例比較了將具有匹配鍵
"a"
的相同 3 個 JSON 物件與這兩個函數合併的結果:mysql> SET @x = '{ "a": 1, "b": 2 }', > @y = '{ "a": 3, "c": 4 }', > @z = '{ "a": 5, "d": 6 }'; mysql> SELECT JSON_MERGE_PATCH(@x, @y, @z) AS Patch, -> JSON_MERGE_PRESERVE(@x, @y, @z) AS Preserve\G *************************** 1. row *************************** Patch: {"a": 5, "b": 2, "c": 4, "d": 6} Preserve: {"a": [1, 3, 5], "b": 2, "c": 4, "d": 6}
JSON_MERGE_PRESERVE(
json_doc
,json_doc
[,json_doc
] ...)合併兩個或多個 JSON 文件並傳回合併結果。如果任何參數為
NULL
,則傳回NULL
。如果任何參數不是有效的 JSON 文件,則會發生錯誤。合併依照下列規則進行。有關其他資訊,請參閱JSON 值的正規化、合併和自動包裝。
相鄰的陣列會合併為單一陣列。
相鄰的物件會合併為單一物件。
純量值會自動包裝為陣列並作為陣列合併。
相鄰的陣列和物件會透過將物件自動包裝為陣列並合併兩個陣列來合併。
mysql> SELECT JSON_MERGE_PRESERVE('[1, 2]', '[true, false]'); +------------------------------------------------+ | JSON_MERGE_PRESERVE('[1, 2]', '[true, false]') | +------------------------------------------------+ | [1, 2, true, false] | +------------------------------------------------+ mysql> SELECT JSON_MERGE_PRESERVE('{"name": "x"}', '{"id": 47}'); +----------------------------------------------------+ | JSON_MERGE_PRESERVE('{"name": "x"}', '{"id": 47}') | +----------------------------------------------------+ | {"id": 47, "name": "x"} | +----------------------------------------------------+ mysql> SELECT JSON_MERGE_PRESERVE('1', 'true'); +----------------------------------+ | JSON_MERGE_PRESERVE('1', 'true') | +----------------------------------+ | [1, true] | +----------------------------------+ mysql> SELECT JSON_MERGE_PRESERVE('[1, 2]', '{"id": 47}'); +---------------------------------------------+ | JSON_MERGE_PRESERVE('[1, 2]', '{"id": 47}') | +---------------------------------------------+ | [1, 2, {"id": 47}] | +---------------------------------------------+ mysql> SELECT JSON_MERGE_PRESERVE('{ "a": 1, "b": 2 }', > '{ "a": 3, "c": 4 }'); +--------------------------------------------------------------+ | JSON_MERGE_PRESERVE('{ "a": 1, "b": 2 }','{ "a": 3, "c":4 }') | +--------------------------------------------------------------+ | {"a": [1, 3], "b": 2, "c": 4} | +--------------------------------------------------------------+ mysql> SELECT JSON_MERGE_PRESERVE('{ "a": 1, "b": 2 }','{ "a": 3, "c": 4 }', > '{ "a": 5, "d": 6 }'); +----------------------------------------------------------------------------------+ | JSON_MERGE_PRESERVE('{ "a": 1, "b": 2 }','{ "a": 3, "c": 4 }','{ "a": 5, "d": 6 }') | +----------------------------------------------------------------------------------+ | {"a": [1, 3, 5], "b": 2, "c": 4, "d": 6} | +----------------------------------------------------------------------------------+
此函數與
JSON_MERGE_PATCH()
相似,但在重要方面有所不同;有關更多資訊,請參閱JSON_MERGE_PATCH() 與 JSON_MERGE_PRESERVE() 的比較。JSON_REMOVE(
json_doc
,path
[,path
] ...)從 JSON 文件中移除資料並傳回結果。如果任何參數為
NULL
,則傳回NULL
。如果json_doc
參數不是有效的 JSON 文件,或任何path
參數不是有效的路徑運算式,或是$
,或包含*
或**
通配符,則會發生錯誤。path
參數會從左到右進行評估。評估一個路徑產生的文件會成為評估下一個路徑的新值。如果要移除的元素不存在於文件中,則不會發生錯誤;在這種情況下,路徑不會影響文件。
mysql> SET @j = '["a", ["b", "c"], "d"]'; mysql> SELECT JSON_REMOVE(@j, '$[1]'); +-------------------------+ | JSON_REMOVE(@j, '$[1]') | +-------------------------+ | ["a", "d"] | +-------------------------+
JSON_REPLACE(
json_doc
,path
,val
[,path
,val
] ...)取代 JSON 文件中現有的值並傳回結果。如果任何參數為
NULL
,則傳回NULL
。如果json_doc
參數不是有效的 JSON 文件,或任何path
參數不是有效的路徑運算式,或包含*
或**
通配符,則會發生錯誤。路徑值對會從左至右評估。評估一對所產生的文件會成為新值,並根據新值評估下一對。
文件中現有路徑的路徑值對會使用新值覆寫現有的文件值。文件中不存在的路徑的路徑值對會被忽略,且沒有任何作用。
最佳化工具可以對
JSON
資料行執行部分就地更新,而不用移除舊文件並將整個新文件寫入資料行。可以使用JSON_REPLACE()
函數且符合JSON 值的部分更新中概述條件的更新陳述式來執行此最佳化。如需比較
JSON_INSERT()
、JSON_REPLACE()
和JSON_SET()
,請參閱JSON_SET()
的討論。mysql> SET @j = '{ "a": 1, "b": [2, 3]}'; mysql> SELECT JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]'); +-----------------------------------------------------+ | JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]') | +-----------------------------------------------------+ | {"a": 10, "b": [2, 3]} | +-----------------------------------------------------+
JSON_SET(
json_doc
,path
,val
[,path
,val
] ...)在 JSON 文件中插入或更新資料並傳回結果。如果
json_doc
或path
為NULL
,或是給定path
時,該路徑無法找到物件,則傳回NULL
。否則,如果json_doc
參數不是有效的 JSON 文件,或任何path
參數不是有效的路徑運算式,或包含*
或**
通配符,則會發生錯誤。路徑值對會從左至右評估。評估一對所產生的文件會成為新值,並根據新值評估下一對。
文件中現有路徑的路徑值對會使用新值覆寫現有的文件值。如果路徑識別下列其中一種值類型,則文件中不存在的路徑的路徑值對會將該值新增至文件中:
現有物件中不存在的成員。成員會新增至物件,並與新值建立關聯。
現有陣列末尾之後的位置。陣列會擴充新值。如果現有值不是陣列,則會自動包裝為陣列,然後使用新值擴充。
否則,文件中不存在的路徑的路徑值對將會被忽略,並且沒有任何作用。
最佳化工具可以對
JSON
資料行執行部分就地更新,而不用移除舊文件並將整個新文件寫入資料行。可以使用JSON_SET()
函數且符合JSON 值的部分更新中概述條件的更新陳述式來執行此最佳化。JSON_SET()
、JSON_INSERT()
和JSON_REPLACE()
函數是相關的:JSON_SET()
會取代現有的值並新增不存在的值。JSON_INSERT()
會插入值,而不會取代現有的值。JSON_REPLACE()
僅取代現有的值。
下列範例說明了這些差異,使用一個在文件中存在的路徑 (
$.a
) 和另一個不存在的路徑 ($.c
):mysql> SET @j = '{ "a": 1, "b": [2, 3]}'; mysql> SELECT JSON_SET(@j, '$.a', 10, '$.c', '[true, false]'); +-------------------------------------------------+ | JSON_SET(@j, '$.a', 10, '$.c', '[true, false]') | +-------------------------------------------------+ | {"a": 10, "b": [2, 3], "c": "[true, false]"} | +-------------------------------------------------+ mysql> SELECT JSON_INSERT(@j, '$.a', 10, '$.c', '[true, false]'); +----------------------------------------------------+ | JSON_INSERT(@j, '$.a', 10, '$.c', '[true, false]') | +----------------------------------------------------+ | {"a": 1, "b": [2, 3], "c": "[true, false]"} | +----------------------------------------------------+ mysql> SELECT JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]'); +-----------------------------------------------------+ | JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]') | +-----------------------------------------------------+ | {"a": 10, "b": [2, 3]} | +-----------------------------------------------------+
取消 JSON 值的引號,並將結果傳回為
utf8mb4
字串。如果參數為NULL
,則傳回NULL
。如果該值以雙引號開始和結束,但不是有效的 JSON 字串字面值,則會發生錯誤。在字串中,除非啟用
NO_BACKSLASH_ESCAPES
SQL 模式,否則某些序列具有特殊含義。這些序列中的每一個都以反斜線 (\
) 開頭,這稱為逸出字元。MySQL 識別表 14.23,「JSON_UNQUOTE() 特殊字元逸出序列」中顯示的逸出序列。對於所有其他逸出序列,反斜線會被忽略。也就是說,逸出字元的解譯方式就像未逸出一樣。例如,\x
就只是x
。這些序列會區分大小寫。例如,\b
會解譯為退格鍵,但\B
會解譯為B
。此函數的兩個簡單用法範例顯示於此
mysql> SET @j = '"abc"'; mysql> SELECT @j, JSON_UNQUOTE(@j); +-------+------------------+ | @j | JSON_UNQUOTE(@j) | +-------+------------------+ | "abc" | abc | +-------+------------------+ mysql> SET @j = '[1, 2, 3]'; mysql> SELECT @j, JSON_UNQUOTE(@j); +-----------+------------------+ | @j | JSON_UNQUOTE(@j) | +-----------+------------------+ | [1, 2, 3] | [1, 2, 3] | +-----------+------------------+
以下範例組顯示
JSON_UNQUOTE
如何處理啟用和停用NO_BACKSLASH_ESCAPES
的跳脫字元mysql> SELECT @@sql_mode; +------------+ | @@sql_mode | +------------+ | | +------------+ mysql> SELECT JSON_UNQUOTE('"\\t\\u0032"'); +------------------------------+ | JSON_UNQUOTE('"\\t\\u0032"') | +------------------------------+ | 2 | +------------------------------+ mysql> SET @@sql_mode = 'NO_BACKSLASH_ESCAPES'; mysql> SELECT JSON_UNQUOTE('"\\t\\u0032"'); +------------------------------+ | JSON_UNQUOTE('"\\t\\u0032"') | +------------------------------+ | \t\u0032 | +------------------------------+ mysql> SELECT JSON_UNQUOTE('"\t\u0032"'); +----------------------------+ | JSON_UNQUOTE('"\t\u0032"') | +----------------------------+ | 2 | +----------------------------+