本節中的函數會修改 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()
則會將第二個值附加到第一個值。
這個範例比較了使用這兩個函數合併相同 3 個 JSON 物件的結果,每個物件都有相符的鍵
"a"
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 | +----------------------------+