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 | +---------+------+---------------------------------------------------------------------------------+