修改JSON值的函数
本节中的函数将修改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"] | +--------------------------------- +在MySQL 5.7中,此函数名为
JSON_APPEND()
。MySQL 8.0不再支持该名称。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文档。同义词
JSON_MERGE_PRESERVE()
; MySQL 8.0.3中已弃用,并可能在将来的版本中删除。mysql>
SELECT JSON_MERGE('[1, 2]', '[true, false]'); +--------------------------------------- + | JSON_MERGE('[1, 2]', '[true, false]') | +--------------------------------------- + | [1, 2, true, false] | +--------------------------------------- + 1 row in set, 1 warning (0.00 sec) mysql>SHOW WARNINGS \G *************************** 1. row *************************** Level : Warning Code : 1287 Message : 'JSON_MERGE' is deprecated and will be removed in a future release. \ Please use JSON_MERGE_PRESERVE/JSON_MERGE_PATCH instead 1 row in set (0.00 sec)有关其他示例,请参见的条目
JSON_MERGE_PRESERVE()
。JSON_MERGE_PATCH(json_doc,json_doc[,json_doc]...)
对两个或多个JSON文档执行符合RFC 7396的合并,并返回合并的结果,而不会保留具有重复密钥的成员。如果至少有一个作为参数传递给该函数的文档无效,则会引发错误。
注意
有关此函数和之间的区别的说明和示例
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
在seond参数中指定相同成员的值来删除成员,如下所示: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()
在MySQL 8.0.3和更高版本中受支持。JSON_MERGE_PATCH()与JSON_MERGE_PRESERVE()的比较。的行为与的行为
JSON_MERGE_PATCH()
相同JSON_MERGE_PRESERVE()
,但以下两个例外:JSON_MERGE_PATCH()
删除与第二个对象中的键匹配的第一个对象中的任何成员,前提是与第二个对象中的键关联的值不是JSONnull
。- 如果第二个对象的成员具有与第一个对象中的成员匹配的键,请
JSON_MERGE_PATCH()
用第二个对象中的值替换第一个对象中的值,而JSON_MERGE_PRESERVE()
将第二个值附加到第一个值中。
此示例比较了将两个相同的3个JSON对象(每个都具有一个匹配的key
"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} | +---------------------------------------------------------------------------------- +此功能已在MySQL 8.0.3中添加为的同义词
JSON_MERGE()
。JSON_MERGE()
现在不推荐使用该功能,并且在将来的MySQL版本中可能会删除该功能。此功能类似于但有很大不同
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
参数不是有效的路径表达式或包含*
或**
通配符,则会发生错误。路径值对从左到右评估。通过评估一对对生成的文档将成为新的价值,以此评估下一对。
文档中现有路径的路径值对使用新值覆盖现有文档值。文档中不存在的路径的路径-值对将被忽略,并且无效。
在MySQL 8.0.4中,优化程序可以对列执行部分就地更新,
JSON
而不是删除旧文档并将新文档全部写入该列。可以针对使用该JSON_REPLACE()
函数并满足JSON值的部分更新中概述的条件的update语句执行此优化。为了进行比较
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文档中插入或更新数据并返回结果。
NULL
如果任何参数是NULL
或path
,则返回,如果给定,则不定位对象。如果json_doc
参数不是有效的JSON文档,或者任何path
参数不是有效的路径表达式或包含*
或**
通配符,则会发生错误。路径值对从左到右评估。通过评估一对对生成的文档将成为新的价值,以此评估下一对。
文档中现有路径的路径值对使用新值覆盖现有文档值。如果路径中标识了以下类型的值之一,则文档中不存在的路径的路径-值对会将值添加到文档中:
- 现有对象中不存在的成员。成员被添加到对象并与新值关联。
- 超出现有数组末尾的位置。用新值扩展数组。如果现有值不是数组,则将其自动包装为数组,然后使用新值进行扩展。
否则,将忽略文档中不存在的路径的路径-值对,并且无效。
在MySQL 8.0.4中,优化程序可以对列执行部分就地更新,
JSON
而不是删除旧文档并将新文档全部写入该列。可以针对使用该JSON_SET()
函数并满足JSON值的部分更新中概述的条件的update语句执行此优化。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_UNQUOTE(json_val)
取消引用JSON值,并将结果作为
utf8mb4
字符串返回。NULL
如果参数为,则返回NULL
。如果该值以双引号开头和结尾,但不是有效的JSON字符串文字,则会发生错误。在字符串中,某些序列具有特殊含义,除非
NO_BACKSLASH_ESCAPES
启用了SQL模式。每个序列都以反斜杠(\
)开头,即转义字符。MySQL可以识别表“ JSON_UNQUOTE()特殊字符转义序列”中所示的转义序列。对于所有其他转义序列,将忽略反斜杠。即,将转义字符解释为好像没有转义。例如,\x
isx
。这些序列区分大小写。例如,\b
被解释为退格,但\B
被解释为B
。表 JSON_UNQUOTE()特殊字符转义序列
转义序列 序列表示的字符 \"
双引号( "
)字符\b
退格字符 \f
换页符 \n
换行符(换行符) \r
回车符 \t
制表符 \\
反斜杠( \
)字符\uXXXX
Unicode值的UTF-8字节 XXXX
下面显示了使用此功能的两个简单示例:
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 | +---------------------------- +