MySQL 5.7新增對JSON支持

最近加入一個新的項目組,在看項目代碼的時候發現很多地方使用的一些操作從來沒用過的,百思不能其解這是什麼操作。

百度了下發現在是Mysql5.7版本以後新增的功能,Mysql提供了一個原生的Json類型,Json值將不再以字符串的形式存儲,而是採用一種允許快速讀取文本元素(document elements)的內部二進制(internal binary)格式。在Json列插入或者更新的時候將會自動驗證Json文本,未通過驗證的文本將產生一個錯誤信息。Json文本採用標準的創建方式,可以使用大多數的比較操作符進行比較操作,例如:=, <, <=, >, >=, <>, != 和 <=>。

MySQL JSON相關函數

MySQL官方列出json相關的函數,完整列表如下:

分類 函數 描述
創建json json_array 創建json數組
  json_object 創建json對象
  json_quote 將json轉成json字符串類型
查詢json json_contains 判斷是否包含某個json值
  json_contains_path 判斷某個路徑下是否包json值
  json_extract 提取json值
  column->path json_extract的簡潔寫法,MySQL 5.7.9開始支持
  column->>path json_unquote(column -> path)的簡潔寫法
  json_keys 提取json中的鍵值爲json數組
  json_search 按給定字符串關鍵字搜索json,返回匹配的路徑
修改json json_append 廢棄,MySQL 5.7.9開始改名爲json_array_append
  json_array_append 末尾添加數組元素,如果原有值是數值或json對象,則轉成數組後,再添加元素
  json_array_insert 插入數組元素
  json_insert 插入值(插入新值,但不替換已經存在的舊值)
  json_merge 合併json數組或對象
  json_remove 刪除json數據
  json_replace 替換值(只替換已經存在的舊值)
  json_set 設置值(替換舊值,並插入不存在的新值)
  json_unquote 去除json字符串的引號,將值轉成string類型
返回json屬性 json_depth 返回json文檔的最大深度
  json_length 返回json文檔的長度
  json_type 返回json值得類型
  json_valid 判斷是否爲合法json文檔

在Mysql5.7版本及之後的版本可以使用column->path作爲JSON_EXTRACT(column, path)的快捷方式。這個函數可以作爲列數據的別名出現在SQL語句中的任意位置,包括WHERE,ORDER BY,和GROUP BY語句。同樣包含SELECT, UPDATE, DELETE,CREATE TABLE和其他SQL語句。->左邊的參數爲JSON數據的列名而不是一個表達式,其右邊參數JSON數據中的某個路徑表達式。

MySQL JOSN相關函數語法

一、創建JSON值的函數

JSON_ARRAY([val[, val] ...])

計算(可能爲空)值列表並返回包含這些值的JSON數組。

mysql> SELECT JSON_ARRAY(1, "abc", NULL, TRUE, CURTIME());
+---------------------------------------------+
| JSON_ARRAY(1, "abc", NULL, TRUE, CURTIME()) |
+---------------------------------------------+
| [1, "abc", null, true, "11:30:24.000000"]   |
+---------------------------------------------+

JSON_OBJECT([keyval[, keyval] ...])

計算(可能爲空)鍵 - 值對列表,並返回包含這些對的JSON對象.如果任何鍵名稱NULL或參數數量爲奇數,則會發生錯誤。

mysql> SELECT JSON_OBJECT('id', 87, 'name', 'carrot');
+-----------------------------------------+
| JSON_OBJECT('id', 87, 'name', 'carrot') |
+-----------------------------------------+
| {"id": 87, "name": "carrot"}            |
+-----------------------------------------+

 

JSON_QUOTE(string)

通過用雙引號字符包裝並轉義內部引號和其他字符,然後將結果作爲utf8mb4字符串返回,將字符串引用爲JSON值 。NULL如果參數是,則 返回 NULL

此函數通常用於生成有效的JSON字符串文字以包含在JSON文檔中。

mysql> SELECT JSON_QUOTE('null'), JSON_QUOTE('"null"');
+--------------------+----------------------+
| JSON_QUOTE('null') | JSON_QUOTE('"null"') |
+--------------------+----------------------+
| "null"             | "\"null\""           |
+--------------------+----------------------+
mysql> SELECT JSON_QUOTE('[1, 2, 3]');
+-------------------------+
| JSON_QUOTE('[1, 2, 3]') |
+-------------------------+
| "[1, 2, 3]"             |
+-------------------------+

二、搜索JSON值的函數

JSON_CONTAINS() 

  • 語法: 

    JSON_CONTAINS(json_doc, val[, path]) 
  • 說明: 
    • 返回0或者1來表示目標JSON文本中是否包含特定值,或者JSON文本的指定路徑下是否包含特定值。
    • 以下情況將返回NULL: 
      • 目標JSON文本或者特定值爲NULl
      • 指定路徑非目標JSON文本下的路徑
    • 以下情況將報錯: 
      • 目標JSON文本不合法
      • 指定路徑不合法
      • 包含* 或者 ** 匹配符
    • 若僅檢查路徑是否存在,使用JSON_CONTAINS_PATH()代替
    • 這個函數中做了以下約定: 
      • 當且僅當兩個標量可比較而且相等時,約定目標表標量中包含候選標量。兩個標量的JSON_TYPE()值相同時約定他們是可比較的,另外類型分別爲INTEGER和DECEMAL的兩個標量也是可比較的
      • 當且僅當目標數組中包含所有的候選數組元素,約定目標數組包含候選數組
      • 當且僅當目標數組中某些元素包含空數組,約定目標數組包含空數組
      • 當且僅當候選對象中所有的鍵值都能在目標對象中找到相同名稱的鍵而且候選鍵值被目標鍵值包含,約定目標對象包含候選對象
      • 其他的情況均爲目標文本不包含候選文本
  • 示例: 
    mysql> SET @j = '{"a": 1, "b": 2, "c": {"d": 4}}';
    mysql> SET @j2 = '1';
    mysql> SELECT JSON_CONTAINS(@j, @j2, '$.a');
    +-------------------------------+
    | JSON_CONTAINS(@j, @j2, '$.a') |
    +-------------------------------+
    |                             1 |
    +-------------------------------+
    mysql> SELECT JSON_CONTAINS(@j, @j2, '$.b');
    +-------------------------------+
    | JSON_CONTAINS(@j, @j2, '$.b') |
    +-------------------------------+
    |                             0 |
    +-------------------------------+
    
    mysql> SET @j2 = '{"d": 4}';
    mysql> SELECT JSON_CONTAINS(@j, @j2, '$.a');
    +-------------------------------+
    | JSON_CONTAINS(@j, @j2, '$.a') |
    +-------------------------------+
    |                             0 |
    +-------------------------------+
    mysql> SELECT JSON_CONTAINS(@j, @j2, '$.c');
    +-------------------------------+
    | JSON_CONTAINS(@j, @j2, '$.c') |
    +-------------------------------+
    |                             1 |
    +-------------------------------+

    JSON_CONTAINS_PATH() 

  • 語法: 

    JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] ...) 
  • 說明: 
    • 返回0或者1表示JSON文本的指定的某個路徑或者某些路徑下是否包含特定值。
    • 當某些參數爲NULL是否返回NULL
    • 以下情況將報錯: 
      • 參數json_doc爲不合法JSON文本
      • path參數中包含不合法的路徑
      • one_or_all參數爲非’one’或者’all’的值
    • 檢測某個路徑中是否包含某個特定值,使用 JSON_CONTAINS()代替
    • 目標文本中如果沒有指定的路徑,則返回0。否則,返回值依賴於one_or_all值: 
      • ’one’: 文本中存在至少一個指定路徑則返回1,否則返回0
      • ‘all’: 文本中包含所有指定路徑則返回1, 否則返回0
  • 示例: 
    mysql> SET @j = '{"a": 1, "b": 2, "c": {"d": 4}}';
    mysql> SELECT JSON_CONTAINS_PATH(@j, 'one', '$.a', '$.e');
    +---------------------------------------------+
    | JSON_CONTAINS_PATH(@j, 'one', '$.a', '$.e') |
    +---------------------------------------------+
    |                                           1 |
    +---------------------------------------------+
    mysql> SELECT JSON_CONTAINS_PATH(@j, 'all', '$.a', '$.e');
    +---------------------------------------------+
    | JSON_CONTAINS_PATH(@j, 'all', '$.a', '$.e') |
    +---------------------------------------------+
    |                                           0 |
    +---------------------------------------------+
    mysql> SELECT JSON_CONTAINS_PATH(@j, 'one', '$.c.d');
    +----------------------------------------+
    | JSON_CONTAINS_PATH(@j, 'one', '$.c.d') |
    +----------------------------------------+
    |                                      1 |
    +----------------------------------------+
    mysql> SELECT JSON_CONTAINS_PATH(@j, 'one', '$.a.d');
    +----------------------------------------+
    | JSON_CONTAINS_PATH(@j, 'one', '$.a.d') |
    +----------------------------------------+
    |                                      0 |
    +----------------------------------------+

    JSON_EXTRACT() 

  • 語法: 

    JSON_EXTRACT(json_doc, path[, path] ...) 
  • 說明: 
    • 返回json_doc中與path參數相匹配的數據。當有參數爲NULl或者文本中未找到指定path時將返回NULL。當參數不合法時將報錯。
    • 返回結果包含所有與path匹配的值。如果返回多個值,則將自動包裝爲數組,其順序爲匹配順序;相反則返回單個匹配值。
    • MySQL5.7.9及之後的版本將支持’->’操作符作爲本函數兩個參數時的便捷寫法。->左邊的參數爲JSON數據的列名而不是一個表達式,其右邊參數JSON數據中的某個路徑表達式。詳細使用方法將在文末詳細闡述。
  • 示例: 
    mysql> SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]');
    +--------------------------------------------+
    | JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]') |
    +--------------------------------------------+
    | 20                                         |
    +--------------------------------------------+
    mysql> SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]', '$[0]');
    +----------------------------------------------------+
    | JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]', '$[0]') |
    +----------------------------------------------------+
    | [20, 10]                                           |
    +----------------------------------------------------+
    mysql> SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[2][*]');
    +-----------------------------------------------+
    | JSON_EXTRACT('[10, 20, [30, 40]]', '$[2][*]') |
    +-----------------------------------------------+
    | [30, 40]                                      |
    +-----------------------------------------------+

     

 

CLOUMN->PATH

  • 語法: 

    CLOUMN->PATH(c->"$.id"
  • 說明: 
    • 當與兩個參數一起使用時, -> 運算符用作JSON_EXTRACT()函數的別名, 左邊是列標識符,右邊是JSON路徑,根據JSON文檔(列值)計算。您可以在SQL語句中的任何位置使用此類表達式代替列標識符
    • 返回結果包含所有與path匹配的值。如果返回多個值,則將自動包裝爲數組,其順序爲匹配順序;相反則返回單個匹配值。
    • MySQL5.7.9及之後的版本將支持’->’操作符作爲本函數兩個參數時的便捷寫法。->左邊的參數爲JSON數據的列名而不是一個表達式,其右邊參數JSON數據中的某個路徑表達式。詳細使用方法將在文末詳細闡述。
  • SELECT這裏顯示 的兩個語句產生相同的輸出:
    mysql> SELECT c, JSON_EXTRACT(c, "$.id"), g
         > FROM jemp
         > WHERE JSON_EXTRACT(c, "$.id") > 1
         > ORDER BY JSON_EXTRACT(c, "$.name");
    +-------------------------------+-----------+------+
    | c                             | c->"$.id" | g    |
    +-------------------------------+-----------+------+
    | {"id": "3", "name": "Barney"} | "3"       |    3 |
    | {"id": "4", "name": "Betty"}  | "4"       |    4 |
    | {"id": "2", "name": "Wilma"}  | "2"       |    2 |
    +-------------------------------+-----------+------+
    3 rows in set (0.00 sec)
    
    mysql> SELECT c, c->"$.id", g
         > FROM jemp
         > WHERE c->"$.id" > 1
         > ORDER BY c->"$.name";
    +-------------------------------+-----------+------+
    | c                             | c->"$.id" | g    |
    +-------------------------------+-----------+------+
    | {"id": "3", "name": "Barney"} | "3"       |    3 |
    | {"id": "4", "name": "Betty"}  | "4"       |    4 |
    | {"id": "2", "name": "Wilma"}  | "2"       |    2 |
    +-------------------------------+-----------+------+
    3 rows in set (0.00 sec)

     

  • 此功能不限 SELECT於此,如下所示:

    mysql> ALTER TABLE jemp ADD COLUMN n INT;
    Query OK, 0 rows affected (0.68 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    mysql> UPDATE jemp SET n=1 WHERE c->"$.id" = "4";
    Query OK, 1 row affected (0.04 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    mysql> SELECT c, c->"$.id", g, n
         > FROM jemp
         > WHERE JSON_EXTRACT(c, "$.id") > 1
         > ORDER BY c->"$.name";
    +-------------------------------+-----------+------+------+
    | c                             | c->"$.id" | g    | n    |
    +-------------------------------+-----------+------+------+
    | {"id": "3", "name": "Barney"} | "3"       |    3 | NULL |
    | {"id": "4", "name": "Betty"}  | "4"       |    4 |    1 |
    | {"id": "2", "name": "Wilma"}  | "2"       |    2 | NULL |
    +-------------------------------+-----------+------+------+
    3 rows in set (0.00 sec)
    
    mysql> DELETE FROM jemp WHERE c->"$.id" = "4";
    Query OK, 1 row affected (0.04 sec)
    
    mysql> SELECT c, c->"$.id", g, n
         > FROM jemp
         > WHERE JSON_EXTRACT(c, "$.id") > 1
         > ORDER BY c->"$.name";
    +-------------------------------+-----------+------+------+
    | c                             | c->"$.id" | g    | n    |
    +-------------------------------+-----------+------+------+
    | {"id": "3", "name": "Barney"} | "3"       |    3 | NULL |
    | {"id": "2", "name": "Wilma"}  | "2"       |    2 | NULL |
    +-------------------------------+-----------+------+------+
    2 rows in set (0.00 sec)

     

  • 這也適用於JSON數組值,如下所示:

    mysql> CREATE TABLE tj10 (a JSON, b INT);
    Query OK, 0 rows affected (0.26 sec)
    
    mysql> INSERT INTO tj10
         > VALUES ("[3,10,5,17,44]", 33), ("[3,10,5,17,[22,44,66]]", 0);
    Query OK, 1 row affected (0.04 sec)
    
    mysql> SELECT a->"$[4]" FROM tj10;
    +--------------+
    | a->"$[4]"    |
    +--------------+
    | 44           |
    | [22, 44, 66] |
    +--------------+
    2 rows in set (0.00 sec)
    
    mysql> SELECT * FROM tj10 WHERE a->"$[0]" = 3;
    +------------------------------+------+
    | a                            | b    |
    +------------------------------+------+
    | [3, 10, 5, 17, 44]           |   33 |
    | [3, 10, 5, 17, [22, 44, 66]] |    0 |
    +------------------------------+------+
    2 rows in set (0.00 sec)

     

  • 支持嵌套數組。使用的表達式 ->計算NULL 好像在目標JSON文檔中找不到匹配的鍵,如下所示:

    mysql> SELECT * FROM tj10 WHERE a->"$[4][1]" IS NOT NULL;
    +------------------------------+------+
    | a                            | b    |
    +------------------------------+------+
    | [3, 10, 5, 17, [22, 44, 66]] |    0 |
    +------------------------------+------+
    
    mysql> SELECT a->"$[4][1]" FROM tj10;
    +--------------+
    | a->"$[4][1]" |
    +--------------+
    | NULL         |
    | 44           |
    +--------------+
    2 rows in set (0.00 sec)

     

  • 這與使用時的情況相同 JSON_EXTRACT()

    mysql> SELECT JSON_EXTRACT(a, "$[4][1]") FROM tj10;
    +----------------------------+
    | JSON_EXTRACT(a, "$[4][1]") |
    +----------------------------+
    | NULL                       |
    | 44                         |
    +----------------------------+
    2 rows in set (0.00 sec)

    COLUMN->>PATH 

    這是一個改進的,不引用的提取操作符,可在MySQL 5.7.13及更高版本中使用。而 ->操作者簡單地提取的值時, ->>在加法運算unquotes所提取的結果。換句話說,給定 JSON列值 column和路徑表達式 path,以下三個表達式返回相同的值:

  • JSON_UNQUOTE( JSON_EXTRACT(columnpath) )

  • JSON_UNQUOTE(column -> path)

  • ->>只要JSON_UNQUOTE(JSON_EXTRACT())允許 ,操作員就可以使用 。這包括(但不限於) SELECT列表,WHERE和 HAVING條款,並ORDER BYGROUP BY條款。

  • 演示->>在mysql客戶端中其他表達式的一些 運算符等價:

    mysql> SELECT * FROM jemp WHERE g > 2;
    +-------------------------------+------+
    | c                             | g    |
    +-------------------------------+------+
    | {"id": "3", "name": "Barney"} |    3 |
    | {"id": "4", "name": "Betty"}  |    4 |
    +-------------------------------+------+
    2 rows in set (0.01 sec)
    
    mysql> SELECT c->'$.name' AS name
        ->     FROM jemp WHERE g > 2;
    +----------+
    | name     |
    +----------+
    | "Barney" |
    | "Betty"  |
    +----------+
    2 rows in set (0.00 sec)
    
    mysql> SELECT JSON_UNQUOTE(c->'$.name') AS name
        ->     FROM jemp WHERE g > 2;
    +--------+
    | name   |
    +--------+
    | Barney |
    | Betty  |
    +--------+
    2 rows in set (0.00 sec)
    
    mysql> SELECT c->>'$.name' AS name
        ->     FROM jemp WHERE g > 2;
    +--------+
    | name   |
    +--------+
    | Barney |
    | Betty  |
    +--------+
    2 rows in set (0.00 sec)

     

  • 此運算符也可以與JSON數組一起使用,如下所示:

    mysql> CREATE TABLE tj10 (a JSON, b INT);
    Query OK, 0 rows affected (0.26 sec)
    
    mysql> INSERT INTO tj10 VALUES
        ->     ('[3,10,5,"x",44]', 33),
        ->     ('[3,10,5,17,[22,"y",66]]', 0);
    Query OK, 2 rows affected (0.04 sec)
    Records: 2  Duplicates: 0  Warnings: 0
    
    mysql> SELECT a->"$[3]", a->"$[4][1]" FROM tj10;
    +-----------+--------------+
    | a->"$[3]" | a->"$[4][1]" |
    +-----------+--------------+
    | "x"       | NULL         |
    | 17        | "y"          |
    +-----------+--------------+
    2 rows in set (0.00 sec)
    
    mysql> SELECT a->>"$[3]", a->>"$[4][1]" FROM tj10;
    +------------+---------------+
    | a->>"$[3]" | a->>"$[4][1]" |
    +------------+---------------+
    | x          | NULL          |
    | 17         | y             |
    +------------+---------------+
    2 rows in set (0.00 sec)

     

  • 與此同時 ->->>運算符總是在輸出中展開EXPLAIN,如下例所示:

    mysql> EXPLAIN SELECT c->>'$.name' AS name
        ->     FROM jemp WHERE g > 2\G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: jemp
       partitions: NULL
             type: range
    possible_keys: i
              key: i
          key_len: 5
              ref: NULL
             rows: 2
         filtered: 100.00
            Extra: Using where
    1 row in set, 1 warning (0.00 sec)
    
    mysql> SHOW WARNINGS\G
    *************************** 1. row ***************************
      Level: Note
       Code: 1003
    Message: /* select#1 */ select
    json_unquote(json_extract(`jtest`.`jemp`.`c`,'$.name')) AS `name` from
    `jtest`.`jemp` where (`jtest`.`jemp`.`g` > 2)
    1 row in set (0.00 sec)

    這類似於MySQL -> 在相同情況下擴展 運算符的方式。

    ->>操作符已添加到MySQL 5.7.13中。

JSON_KEYS() 

  • 語法: 

    JSON_KEYS(json_doc[, path]) 
  • 說明: 
    • 返回JSON對象的頂層目錄的所有key值或者path指定路徑下的頂層目錄的所有key所組成的JSON數組。
    • 以下情況返回NULL 
      • 必填參數爲NULL
      • json_doc非對象(爲數組等)
      • 當給定path,但是在JSON中未找到
    • 以下情況報錯 
      • json_doc爲不合法的JSON文本
      • path爲不合法的路徑表達
      • 包含 * 或者 ** 通配符
    • 當目標對象爲空時,返回值爲空。返回結果不包含頂層目錄下的嵌套的目錄中的key
  • 示例: 
    mysql> SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}');
    +---------------------------------------+
    | JSON_KEYS('{"a": 1, "b": {"c": 30}}') |
    +---------------------------------------+
    | ["a", "b"]                            |
    +---------------------------------------+
    mysql> SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}', '$.b');
    +----------------------------------------------+
    | JSON_KEYS('{"a": 1, "b": {"c": 30}}', '$.b') |
    +----------------------------------------------+
    | ["c"]                                        |
    +----------------------------------------------+

    JSON_SEARCH() 

  • 語法: 

    JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] ...]) 
  • 說明: 
    • 返回JSON包含指定字符串的路徑。
    • 以下情況將返回NULL 
      • json_doc, search_str 或path 爲NULL
      • 文本中不包含path
      • search_str未找到
    • 以下情況將報錯 
      • json_doc不合法
      • path不合法
      • one_or_all 不是one 或者all
      • escape_char 不是一個常量表達式
    • one_or_all的作用 
      • ’one’:當查找操作找到第一個匹配對象,並將結果路徑返回後就停止查找。
      • ‘all’:將返回所有的匹配結果路徑,結果中不包含重複路徑。如果返回結果集中包含多個字符串,將自動封裝爲一個數組,元素的排序順序無意義。
    • 在search_str中,通配符’%’和’‘可以如同LIKE操作上一樣運行。’%’可以匹配多個字符(包括0個字符),’‘則僅可匹配一個字符。
    • ‘%’或’_’作爲特殊字符出現時,需要使用轉義字符進行轉義。當escape_char參數爲NULL或者不存在的情況下,系統默認使用’\’作爲轉義字符。escape_char參數必須要常量(爲空或者一個字符)
    • 對於通配符的處理上與LIKE操作不同之處在於,JSON_SEARCH()中的通配符在編譯時的計算結果必須要是常量,而不像LIKE僅需在執行時爲常量。例如:在prepared Statement中使用JSON_SEARCH(), escape_char參數使用’?’作爲參數,那麼這個參數在執行時可能是常量,而不是在編譯的時候。(這句話自己也沒怎麼懂,想了很久沒想到該怎麼翻譯)
  • 示例: 
    mysql> SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]';
    
    mysql> SELECT JSON_SEARCH(@j, 'one', 'abc');
    +-------------------------------+
    | JSON_SEARCH(@j, 'one', 'abc') |
    +-------------------------------+
    | "$[0]"                        |
    +-------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', 'abc');
    +-------------------------------+
    | JSON_SEARCH(@j, 'all', 'abc') |
    +-------------------------------+
    | ["$[0]", "$[2].x"]            |
    +-------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', 'ghi');
    +-------------------------------+
    | JSON_SEARCH(@j, 'all', 'ghi') |
    +-------------------------------+
    | NULL                          |
    +-------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', '10');
    +------------------------------+
    | JSON_SEARCH(@j, 'all', '10') |
    +------------------------------+
    | "$[1][0].k"                  |
    +------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$');
    +-----------------------------------------+
    | JSON_SEARCH(@j, 'all', '10', NULL, '$') |
    +-----------------------------------------+
    | "$[1][0].k"                             |
    +-----------------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[*]');
    +--------------------------------------------+
    | JSON_SEARCH(@j, 'all', '10', NULL, '$[*]') |
    +--------------------------------------------+
    | "$[1][0].k"                                |
    +--------------------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$**.k');
    +---------------------------------------------+
    | JSON_SEARCH(@j, 'all', '10', NULL, '$**.k') |
    +---------------------------------------------+
    | "$[1][0].k"                                 |
    +---------------------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[*][0].k');
    +-------------------------------------------------+
    | JSON_SEARCH(@j, 'all', '10', NULL, '$[*][0].k') |
    +-------------------------------------------------+
    | "$[1][0].k"                                     |
    +-------------------------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[1]');
    +--------------------------------------------+
    | JSON_SEARCH(@j, 'all', '10', NULL, '$[1]') |
    +--------------------------------------------+
    | "$[1][0].k"                                |
    +--------------------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[1][0]');
    +-----------------------------------------------+
    | JSON_SEARCH(@j, 'all', '10', NULL, '$[1][0]') |
    +-----------------------------------------------+
    | "$[1][0].k"                                   |
    +-----------------------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', 'abc', NULL, '$[2]');
    +---------------------------------------------+
    | JSON_SEARCH(@j, 'all', 'abc', NULL, '$[2]') |
    +---------------------------------------------+
    | "$[2].x"                                    |
    +---------------------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', '%a%');
    +-------------------------------+
    | JSON_SEARCH(@j, 'all', '%a%') |
    +-------------------------------+
    | ["$[0]", "$[2].x"]            |
    +-------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', '%b%');
    +-------------------------------+
    | JSON_SEARCH(@j, 'all', '%b%') |
    +-------------------------------+
    | ["$[0]", "$[2].x", "$[3].y"]  |
    +-------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', '%b%', NULL, '$[0]');
    +---------------------------------------------+
    | JSON_SEARCH(@j, 'all', '%b%', NULL, '$[0]') |
    +---------------------------------------------+
    | "$[0]"                                      |
    +---------------------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', '%b%', NULL, '$[2]');
    +---------------------------------------------+
    | JSON_SEARCH(@j, 'all', '%b%', NULL, '$[2]') |
    +---------------------------------------------+
    | "$[2].x"                                    |
    +---------------------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', '%b%', NULL, '$[1]');
    +---------------------------------------------+
    | JSON_SEARCH(@j, 'all', '%b%', NULL, '$[1]') |
    +---------------------------------------------+
    | NULL                                        |
    +---------------------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', '%b%', '', '$[1]');
    +-------------------------------------------+
    | JSON_SEARCH(@j, 'all', '%b%', '', '$[1]') |
    +-------------------------------------------+
    | NULL                                      |
    +-------------------------------------------+
    
    mysql> SELECT JSON_SEARCH(@j, 'all', '%b%', '', '$[3]');
    +-------------------------------------------+
    | JSON_SEARCH(@j, 'all', '%b%', '', '$[3]') |
    +-------------------------------------------+
    | "$[3].y"                                  |
    +-------------------------------------------+

    三、修改JSON值的函數

  • JSON_APPEND(json_docpathval[, pathval] ...)

    將值附加到JSON文檔中指定數組的末尾並返回結果。這個函數JSON_ARRAY_APPEND() 在MySQL 5.7.9中被重命名爲; 該別名JSON_APPEND()現已在MySQL 5.7中棄用,並在MySQL 8.0中刪除。

JSON_ARRAY_APPEND()

  • 語法:

    JSON_ARRAY_APPEND(json_doc, path, val[, path, val] ...)
  • 說明:

    • 在指定的數組末尾以JSON文本形式追加指定的值並返回。當參數中包含NULL時,返回NULL。
    • 以下情況將報錯 
      • json_doc不合法
      • path 不合法
      • 包含* 或者 ** 通配符
    • 鍵值對採用自左到右的順序進行追加。追加一對鍵值後的新值將成爲下一對鍵值追加的目標。
    • 如果指定目錄下爲標量或者對象值,則會被封裝爲數組,然後將新的值加入到數組中。對於不包含任何值得鍵值對將直接忽略。
  • 示例:
    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_ARRAY_INSERT(json_doc, path, val[, path, val] ...) 
  • 說明: 
    • 更新一個JSON文本,向文本中插入一個數組,然後返回修改後的文本。如果參數爲NULL,則返回NULL。
    • 以下情況報錯 
      • json_doc參數不合法
      • path不合法
      • 包含 * 或者 ** 通配符
      • 不是以數組標示結尾
    • 鍵值對採用自左到右的順序進行插入,插入一對後的新值將作爲下一對插入的目標。
    • 對於不包含任何值得鍵值對將直接忽略。如果path指定的是一個數組元素,則其對應的值將插入到該元素右邊的任意位置;如果path指定的是數組的末尾,則其值將插入到該數組末尾。
    • 執行插入操作後,其元素位置將發生變化,也將影響後續插入數據的位置定義。如最後的示例中,第二個插入數據並未出現數數據庫中,是因爲第一次插入操作後,原語句中定義的位置在新數據中未找到指定的元素,從而被忽略。
  • 示例: 
    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_docpathval[, pathval] ...)

將數據插入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_docjson_doc[, json_doc] ...)

合併兩個或多個JSON文檔。同義詞 JSON_MERGE_PRESERVE(); 在MySQL 5.7.22中已棄用,並且在將來的版本中將被刪除。

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_PATCH(json_docjson_doc[, json_doc] ...)

執行 符合RFC 7396的兩個或多個JSON文檔的合併,並返回合併的結果,而不保留具有重複鍵的成員。如果至少有一個作爲參數傳遞給此函數的文檔無效,則引發錯誤。

注意

有關此函數與之間差異的解釋和示例JSON_MERGE_PRESERVE(),請參閱與 JSON_MERGE_PRESERVE()相比較的JSON_MERGE_PATCH()

JSON_MERGE_PATCH() 執行合併如下:

  1. 如果第一個參數不是對象,則合併的結果與將空對象與第二個參數合併的結果相同。

  2. 如果第二個參數不是對象,則合併的結果是第二個參數。

  3. 如果兩個參數都是對象,則合併的結果是具有以下成員的對象:

    • 第一個對象的所有成員沒有在第二個對象中具有相同鍵的相應成員。

    • 第二個對象的所有成員在第一個對象中沒有對應的鍵,其值不是JSON null文字。

    • 具有在第一個和第二個對象中存在的鍵的所有成員,並且其在第二個對象中的值不是JSON null 文字。這些成員的值是以遞歸方式將第一個對象中的值與第二個對象中的值合併的結果。

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 5.7.22及更高版本支持。

JSON_MERGE_PATCH()與JSON_MERGE_PRESERVE()進行比較。  的行爲JSON_MERGE_PATCH()是一樣的是JSON_MERGE_PRESERVE(),有以下兩種情況例外:

  • JSON_MERGE_PATCH()使用第二個對象中的匹配鍵刪除第一個對象中的任何成員,前提是與第二個對象中的鍵關聯的值不是JSON null

  • 如果第二個對象的成員具有與第一個對象中的成員匹配的鍵,則將第一個對象中 的值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_docjson_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 5.7.22中作爲同義詞添加 JSON_MERGE()。該 JSON_MERGE()函數現已棄用,並且將在MySQL的未來版本中刪除。

    該功能與JSON_MERGE_PATCH()重要方面類似但不同 ; 有關詳細信息,請參閱 JSON_MERGE_PATCH()與JSON_MERGE_PRESERVE()進行比較。

JSON_REMOVE(json_docpath[, 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_docpathval[, pathval] ...)

替換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_REPLACE(@j, '$.a', 10, '$.c', '[true, false]');
+-----------------------------------------------------+
| JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]') |
+-----------------------------------------------------+
| {"a": 10, "b": [2, 3]}                              |
+-----------------------------------------------------+

 

JSON_SET(json_docpathval[, pathval] ...)

在JSON文檔中插入或更新數據並返回結果。返回NULL如果任何參數是 NULLpath,如果給,不定位的對象。如果發生錯誤 json_doc的參數是不是一個有效的JSON文檔或任何path參數是不是有效的路徑表達式或包含一個 ***通配符。

路徑值對從左到右進行評估。通過評估一對產生的文檔成爲評估下一對的新值。

文檔中現有路徑的路徑值對使用新值覆蓋現有文檔值。如果路徑標識以下類型的值之一,則文檔中不存在路徑的路徑值對會將值添加到文檔中:

  • 不存在於現有對象中的成員。該成員將添加到對象並與新值關聯。

  • 位於現有數組末尾的位置。該數組使用新值進行擴展。如果現有值不是數組,則將其作爲數組自動包裝,然後使用新值進行擴展。

否則,將忽略文檔中不存在路徑的路徑 - 值對,但不起作用。

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啓用S​​QL模式,否則某些序列具有特殊含義。這些序列中的每一個都以反斜槓(\)開頭,稱爲 轉義字符。MySQL識別 表12.21“JSON_UNQUOTE()特殊字符轉義序列”中顯示的轉義序列。對於所有其他轉義序列,將忽略反斜槓。也就是說,轉義字符被解釋爲好像它沒有被轉義。例如,\x就是x。這些序列區分大小寫。例如, \b被解釋爲退格,但 \B被解釋爲B

表12.21 JSON_UNQUOTE()特殊字符轉義序列

逃脫序列 由Sequence表示的字符
\" 雙引號(")字符
\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_UNQUOTENO_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                         |
+----------------------------+

四、返回JSON值屬性的函數

JSON_DEPTH(json_doc)

返回JSON文檔的最大深度。NULL如果參數是,則 返回 NULL。如果參數不是有效的JSON文檔,則會發生錯誤。

空數組,空對象或標量值具有深度1.僅包含深度爲1的元素的非空數組或僅包含深度爲1的成員值的非空對象具有深度2.否則,JSON文檔的深度大於2。

mysql> SELECT JSON_DEPTH('{}'), JSON_DEPTH('[]'), JSON_DEPTH('true');
+------------------+------------------+--------------------+
| JSON_DEPTH('{}') | JSON_DEPTH('[]') | JSON_DEPTH('true') |
+------------------+------------------+--------------------+
|                1 |                1 |                  1 |
+------------------+------------------+--------------------+
mysql> SELECT JSON_DEPTH('[10, 20]'), JSON_DEPTH('[[], {}]');
+------------------------+------------------------+
| JSON_DEPTH('[10, 20]') | JSON_DEPTH('[[], {}]') |
+------------------------+------------------------+
|                      2 |                      2 |
+------------------------+------------------------+
mysql> SELECT JSON_DEPTH('[10, {"a": 20}]');
+-------------------------------+
| JSON_DEPTH('[10, {"a": 20}]') |
+-------------------------------+
|                             3 |
+-------------------------------+

JSON_LENGTH(json_doc[, path])

返回JSON文檔的長度,或者,如果path給出參數,則返回 由路徑標識的文檔中的值的長度。返回NULL如果任何參數 NULLpath 參數不文檔中確定的值。如果json_doc參數不是有效的JSON文檔或 path參數不是有效的路徑表達式或包含*或 **通配符,則會發生錯誤。

文件的長度確定如下:

  • 標量的長度爲1。

  • 數組的長度是數組元素的數量。

  • 對象的長度是對象成員的數量。

  • 長度不計算嵌套數組或對象的長度。

    mysql> SELECT JSON_LENGTH('[1, 2, {"a": 3}]');
    +---------------------------------+
    | JSON_LENGTH('[1, 2, {"a": 3}]') |
    +---------------------------------+
    |                               3 |
    +---------------------------------+
    mysql> SELECT JSON_LENGTH('{"a": 1, "b": {"c": 30}}');
    +-----------------------------------------+
    | JSON_LENGTH('{"a": 1, "b": {"c": 30}}') |
    +-----------------------------------------+
    |                                       2 |
    +-----------------------------------------+
    mysql> SELECT JSON_LENGTH('{"a": 1, "b": {"c": 30}}', '$.b');
    +------------------------------------------------+
    | JSON_LENGTH('{"a": 1, "b": {"c": 30}}', '$.b') |
    +------------------------------------------------+
    |                                              1 |
    +------------------------------------------------+

     

JSON_TYPE(json_val)

返回utf8mb4表示JSON值類型的字符串。這可以是對象,數組或標量類型,如下所示:

mysql> SET @j = '{"a": [10, true]}';
mysql> SELECT JSON_TYPE(@j);
+---------------+
| JSON_TYPE(@j) |
+---------------+
| OBJECT        |
+---------------+
mysql> SELECT JSON_TYPE(JSON_EXTRACT(@j, '$.a'));
+------------------------------------+
| JSON_TYPE(JSON_EXTRACT(@j, '$.a')) |
+------------------------------------+
| ARRAY                              |
+------------------------------------+
mysql> SELECT JSON_TYPE(JSON_EXTRACT(@j, '$.a[0]'));
+---------------------------------------+
| JSON_TYPE(JSON_EXTRACT(@j, '$.a[0]')) |
+---------------------------------------+
| INTEGER                               |
+---------------------------------------+
mysql> SELECT JSON_TYPE(JSON_EXTRACT(@j, '$.a[1]'));
+---------------------------------------+
| JSON_TYPE(JSON_EXTRACT(@j, '$.a[1]')) |
+---------------------------------------+
| BOOLEAN                               |
+---------------------------------------+

JSON_TYPE()返回 NULL如果參數爲 NULL

mysql> SELECT JSON_TYPE(NULL);
+-----------------+
| JSON_TYPE(NULL) |
+-----------------+
| NULL            |
+-----------------+

如果參數不是有效的JSON值,則會發生錯誤:

mysql> SELECT JSON_TYPE(1);
ERROR 3146 (22032): Invalid data type for JSON data in argument 1
to function json_type; a JSON string or JSON type is required.

對於NULL非非錯誤結果,以下列表描述了可能的 JSON_TYPE()返回值:

  • 純JSON類型:

    • OBJECT:JSON對象

    • ARRAY:JSON數組

    • BOOLEAN:JSON真假文字

    • NULL:JSON null文字

  • 數字類型:

  • 時間類型:

  • 字符串類型:

  • 二進制類型:

  • 所有其他類型:

    • OPAQUE (原始位)

JSON_VALID(val)

返回0或1以指示值是否爲有效JSON。NULL如果參數是,則 返回NULL

mysql> SELECT JSON_VALID('{"a": 1}');
+------------------------+
| JSON_VALID('{"a": 1}') |
+------------------------+
|                      1 |
+------------------------+
mysql> SELECT JSON_VALID('hello'), JSON_VALID('"hello"');
+---------------------+-----------------------+
| JSON_VALID('hello') | JSON_VALID('"hello"') |
+---------------------+-----------------------+
|                   0 |                     1 |
+---------------------+-----------------------+

 

官方文檔有更詳細的說明的舉例,請參考https://dev.mysql.com/doc/refman/5.7/en/json-function-reference.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章