Dans MariaDB, JSON_TABLE()
est une fonction intégrée qui convertit les données JSON en une forme relationnelle.
En d'autres termes, il vous permet de renvoyer un document JSON sous forme de tableau.
Le JSON_TABLE()
la fonction a été introduite dans MariaDB 10.6.0.
Syntaxe
La syntaxe ressemble à ceci :
JSON_TABLE(json_doc,
context_path COLUMNS (column_list)
) [AS] alias
Où column_list
va comme ceci :
column[, column][, ...]
Où column
va comme ceci :
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)
Où on_empty
va comme ceci :
{NULL | DEFAULT string | ERROR} ON EMPTY
Et on_error
va comme ceci :
{NULL | DEFAULT string | ERROR} ON ERROR
Exemple
Voici un exemple pour illustrer.
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;
Résultat :
+------+------+--------+ | name | type | weight | +------+------+--------+ | Wag | Dog | 20 | | Bark | Dog | 10 | | Meow | Cat | 7 | +------+------+--------+
Ici, nous nommons chaque colonne de la table, spécifions son type de données, puis spécifions le chemin du document JSON qui s'appliquera à cette colonne.
Donc, nous avons appelé notre première colonne name
, puis mappé le nœud appelé name
du document JSON à cette colonne.
Colonnes d'ordinanalité
Le FOR ORDINALITY
l'option peut être utilisée pour compter les lignes, à partir de 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;
Résultat :
+------+---------+----------+--------+ | id | name | type | weight | +------+---------+----------+--------+ | 1 | Scratch | Cat | 8 | | 2 | Bruce | Kangaroo | 100 | | 3 | Hop | Kangaroo | 130 | +------+---------+----------+--------+
Vérification de l'existence d'un chemin
Vous pouvez utiliser le EXISTS
clause pour vérifier l'existence d'un chemin. Si le chemin existe dans le document JSON, le résultat est 1
. S'il n'existe pas, 0
est renvoyé.
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;
Résultat :
+-------+----------+------------+ | name | type | has_weight | +-------+----------+------------+ | Punch | Kangaroo | 1 | | Snap | Cat | 1 | | Ruff | Dog | 0 | +-------+----------+------------+
Chemins imbriqués
Le NESTED PATH
La clause vous permet de traiter des documents JSON imbriqués. Lorsque vous utilisez cette clause, elle convertit les structures JSON imbriquées en plusieurs lignes.
Exemple :
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;
Résultat :
+-------------------------+------+ | 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 | +-------------------------+------+
Traitement des chemins vides
Le ON EMPTY
La clause spécifie ce qui sera fait lorsque l'élément spécifié par le chemin de recherche est manquant dans le document JSON.
Exemple :
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;
Résultat :
+-------+----------+--------+ | name | type | weight | +-------+----------+--------+ | Punch | Kangaroo | 200 | | Snap | Cat | 12 | | Ruff | N/A | NULL | +-------+----------+--------+
Dans cet exemple, Ruff
n'a pas de champ de type et donc N/A
est retourné. C'est parce que j'ai spécifié cela dans le ON EMPTY
clause pour ce champ.
Traitement des erreurs
Le ON ERROR
La clause spécifie ce qui doit être fait si une erreur de structure JSON se produit lors de la tentative d'extraction de la valeur du document.
Une erreur de structure JSON se produit uniquement lorsque vous tentez de convertir un JSON non scalaire (tableau ou objet) en une valeur scalaire. Lorsque ON ERROR
la clause n'est pas présente, NULL ON ERROR
est implicite.
Voici un exemple de gestion d'une erreur de structure 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;
Résultat :
+-------------------------+-------+ | product | sizes | +-------------------------+-------+ | Left Handed Screwdriver | Oops! | | Long Weight | Oops! | | Bottomless Coffee Cup | None | +-------------------------+-------+
Ici, j'ai spécifié une chaîne (Oops!
) à utiliser chaque fois qu'une erreur de structure JSON s'est produite.
Dans ce cas, j'ai également inclus le ON EMPTY
clause. Cela démontre que le ON ERROR
et le ON EMPTY
clause peut être utilisée dans la même instruction.
Cependant, il est important de noter qu'une erreur de conversion de type de données (par exemple, une tentative de stockage d'une valeur non entière dans un champ entier ou une colonne varchar tronquée) n'est pas considérée comme une erreur JSON et ne déclenchera donc pas le ON ERROR
clause. Au lieu de cela, il produira des avertissements.
Voici un exemple pour illustrer ce que je veux dire :
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;
Résultat :
+-------+------+ | name | type | +-------+------+ | Punch | 0 | | Snap | 0 | | Ruff | 0 | +-------+------+ 3 rows in set, 3 warnings (0.000 sec)
Montrons les avertissements :
SHOW WARNINGS;
Résultat :
+---------+------+---------------------------------------------------------------------------------+ | 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 | +---------+------+---------------------------------------------------------------------------------+