MariaDB
 sql >> Database >  >> RDS >> MariaDB

Spiegazione di MariaDB JSON_TABLE()

In MariaDB, JSON_TABLE() è una funzione integrata che converte i dati JSON in un modulo relazionale.

In altre parole, ti consente di restituire un documento JSON come tabella.

Il JSON_TABLE() la funzione è stata introdotta in MariaDB 10.6.0.

Sintassi

La sintassi è questa:

JSON_TABLE(json_doc, 
          context_path COLUMNS (column_list)
) [AS] alias

Dove column_list va così:

column[, column][, ...]

Dove column va così:

name FOR ORDINALITY
    |  name type PATH value_path path [on_empty] [on_error]
    |  name type EXISTS PATH value_path
    |  NESTED [PATH] path COLUMNS (column_list)

Dove on_empty va così:

{NULL | DEFAULT string | ERROR} ON EMPTY

E on_error va così:

{NULL | DEFAULT string | ERROR} ON ERROR

Esempio

Ecco un esempio da dimostrare.

SET @json_document = '
[
    { "name": "Wag", "type": "Dog", "weight": 20 },
    { "name": "Bark", "type": "Dog", "weight": 10 },
    { "name": "Meow", "type": "Cat", "weight": 7 }
]
';

SELECT * FROM JSON_TABLE(@json_document, '$[*]'
    COLUMNS (
    name VARCHAR(255) PATH '$.name', 
    type VARCHAR(50) PATH '$.type',
    weight INT PATH '$.weight' 
    )
) AS json_table;

Risultato:

+------+------+--------+
| name | type | weight |
+------+------+--------+
| Wag  | Dog  |     20 |
| Bark | Dog  |     10 |
| Meow | Cat  |      7 |
+------+------+--------+

Qui denominiamo ogni colonna per la tabella, specifichiamo il suo tipo di dati, quindi specifichiamo il percorso dal documento JSON che si applicherà a quella colonna.

Quindi, abbiamo chiamato la nostra prima colonna name , e quindi mappato il nodo chiamato name dal documento JSON a quella colonna.

Colonne Ordinalità

Il FOR ORDINALITY l'opzione può essere utilizzata per contare le righe, a partire da 1 .

SET @json_document = '
[
    { "name": "Scratch", "type": "Cat", "weight": 8 },
    { "name": "Bruce", "type": "Kangaroo", "weight": 100 },
    { "name": "Hop", "type": "Kangaroo", "weight": 130 }
]
';
SELECT * FROM JSON_TABLE(@json_document, '$[*]'
    COLUMNS (
    id FOR ORDINALITY,
    name VARCHAR(255) PATH '$.name', 
    type VARCHAR(50) PATH '$.type',
    weight INT PATH '$.weight' 
    )
) AS json_table;

Risultato:

+------+---------+----------+--------+
| id   | name    | type     | weight |
+------+---------+----------+--------+
|    1 | Scratch | Cat      |      8 |
|    2 | Bruce   | Kangaroo |    100 |
|    3 | Hop     | Kangaroo |    130 |
+------+---------+----------+--------+

Verifica dell'esistenza di un percorso

Puoi usare il EXISTS clausola per verificare l'esistenza di un percorso. Se il percorso esiste nel documento JSON, il risultato è 1 . Se non esiste, 0 viene restituito.

SET @json_document = '
[
    { "name": "Punch", "type": "Kangaroo", "weight": 200 },
    { "name": "Snap", "type": "Cat", "weight": 12 },
    { "name": "Ruff", "type": "Dog" }
]
';
SELECT * FROM JSON_TABLE(@json_document, '$[*]'
    COLUMNS (
    name  VARCHAR(255) PATH '$.name', 
    type VARCHAR(50) PATH '$.type',
    has_weight INT EXISTS PATH '$.weight' 
    )
) AS json_table;

Risultato:

+-------+----------+------------+
| name  | type     | has_weight |
+-------+----------+------------+
| Punch | Kangaroo |          1 |
| Snap  | Cat      |          1 |
| Ruff  | Dog      |          0 |
+-------+----------+------------+

Percorsi nidificati

Il NESTED PATH La clausola consente di gestire documenti JSON nidificati. Quando usi questa clausola, converte le strutture JSON nidificate in più righe.

Esempio:

SET @json_document = '
[
    { "product": "Left Handed Screwdriver", "sizes": [ "S", "M", "L" ] },
    { "product": "Long Weight", "sizes": [ "S", "L", "XL" ] },
    { "product": "Bottomless Coffee Cup" }
]
';
SELECT * FROM JSON_TABLE(@json_document, '$[*]'
    COLUMNS (
    product  VARCHAR(255) PATH '$.product', 
    NESTED PATH '$.sizes[*]' columns (
        size VARCHAR(2) PATH '$'
        )
    )
) AS json_table;

Risultato:

+-------------------------+------+
| product                 | size |
+-------------------------+------+
| Left Handed Screwdriver | S    |
| Left Handed Screwdriver | M    |
| Left Handed Screwdriver | L    |
| Long Weight             | S    |
| Long Weight             | L    |
| Long Weight             | XL   |
| Bottomless Coffee Cup   | NULL |
+-------------------------+------+

Gestire percorsi vuoti

Il ON EMPTY La clausola specifica cosa verrà fatto quando l'elemento specificato dal percorso di ricerca non è presente nel documento JSON.

Esempio:

SET @json_document = '
[
    { "name": "Punch", "type": "Kangaroo", "weight": 200 },
    { "name": "Snap", "type": "Cat", "weight": 12 },
    { "name": "Ruff"}
]
';
SELECT * FROM JSON_TABLE(@json_document, '$[*]'
    COLUMNS (
    name  VARCHAR(255) PATH '$.name', 
    type VARCHAR(50) PATH '$.type' DEFAULT "N/A" ON EMPTY,
    weight INT PATH '$.weight'
    )
) AS json_table;

Risultato:

+-------+----------+--------+
| name  | type     | weight |
+-------+----------+--------+
| Punch | Kangaroo |    200 |
| Snap  | Cat      |     12 |
| Ruff  | N/A      |   NULL |
+-------+----------+--------+

In questo esempio, Ruff non ha un campo tipo e quindi N/A viene restituito. Questo perché l'ho specificato nel ON EMPTY clausola per quel campo.

Gestire gli errori

Il ON ERROR La clausola specifica cosa dovrebbe essere fatto se si verifica un errore di struttura JSON durante il tentativo di estrarre il valore dal documento.

Un errore di struttura JSON si verifica solo quando si tenta di convertire un valore JSON non scalare (array o oggetto) in un valore scalare. Quando il ON ERROR la clausola non è presente, NULL ON ERROR è implicito.

Ecco un esempio di gestione di un errore di struttura JSON:

SET @json_document = '
[
    { "product": "Left Handed Screwdriver", "sizes": [ "S", "M", "L" ] },
    { "product": "Long Weight", "sizes": [ "S", "L", "XL" ] },
    { "product": "Bottomless Coffee Cup" }
]
';
SELECT * FROM JSON_TABLE(@json_document, '$[*]'
    COLUMNS (
    product  VARCHAR(255) PATH '$.product', 
    sizes VARCHAR(5) PATH '$.sizes' 
        DEFAULT 'Oops!' ON ERROR
        DEFAULT 'None' ON EMPTY
    )
) AS json_table;

Risultato:

+-------------------------+-------+
| product                 | sizes |
+-------------------------+-------+
| Left Handed Screwdriver | Oops! |
| Long Weight             | Oops! |
| Bottomless Coffee Cup   | None  |
+-------------------------+-------+

Qui, ho specificato una stringa (Oops! ) da utilizzare ogni volta che si verifica un errore di struttura JSON.

In questo caso ho incluso anche il ON EMPTY clausola. Ciò dimostra che sia ON ERROR e il ON EMPTY la clausola può essere utilizzata nella stessa istruzione.

Tuttavia, è importante notare che un errore di conversione del tipo di dati (ad esempio, un tentativo di memorizzare un valore non intero in un campo intero o una colonna varchar troncata) non è considerato un errore JSON e quindi non attiverà il ON ERROR clausola. Invece, produrrà avvisi.

Ecco un esempio per illustrare cosa intendo:

SET @json_document = '
[
    { "name": "Punch", "type": "Kangaroo" },
    { "name": "Snap", "type": "Cat" },
    { "name": "Ruff", "type": "Dog" }
]
';
SELECT * FROM JSON_TABLE(@json_document, '$[*]'
    COLUMNS (
    name  VARCHAR(255) PATH '$.name', 
    type INT PATH '$.type' DEFAULT 'Oops!' ON ERROR
    )
) AS json_table;

Risultato:

+-------+------+
| name  | type |
+-------+------+
| Punch |    0 |
| Snap  |    0 |
| Ruff  |    0 |
+-------+------+
3 rows in set, 3 warnings (0.000 sec)

Mostriamo gli avvisi:

SHOW WARNINGS;

Risultato:

+---------+------+---------------------------------------------------------------------------------+
| Level   | Code | Message                                                                         |
+---------+------+---------------------------------------------------------------------------------+
| Warning | 1366 | Incorrect integer value: 'Kangaroo' for column ``.`(temporary)`.`type` at row 1 |
| Warning | 1366 | Incorrect integer value: 'Cat' for column ``.`(temporary)`.`type` at row 2      |
| Warning | 1366 | Incorrect integer value: 'Dog' for column ``.`(temporary)`.`type` at row 3      |
+---------+------+---------------------------------------------------------------------------------+