V MariaDB, JSON_TABLE()
je vestavěná funkce, která převádí data JSON do relační formy.
Jinými slovy, umožňuje vám vrátit dokument JSON jako tabulku.
JSON_TABLE()
funkce byla představena v MariaDB 10.6.0.
Syntaxe
Syntaxe vypadá takto:
JSON_TABLE(json_doc,
context_path COLUMNS (column_list)
) [AS] alias
Kde column_list
vypadá takto:
column[, column][, ...]
Kde column
vypadá takto:
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)
Kde on_empty
vypadá takto:
{NULL | DEFAULT string | ERROR} ON EMPTY
A on_error
vypadá takto:
{NULL | DEFAULT string | ERROR} ON ERROR
Příklad
Zde je příklad k demonstraci.
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;
Výsledek:
+------+------+--------+ | name | type | weight | +------+------+--------+ | Wag | Dog | 20 | | Bark | Dog | 10 | | Meow | Cat | 7 | +------+------+--------+
Zde pojmenujeme každý sloupec tabulky, určíme jeho datový typ a poté určíme cestu z dokumentu JSON, která se bude na daný sloupec vztahovat.
Náš první sloupec jsme tedy nazvali name
a poté namapoval uzel s názvem name
z dokumentu JSON do tohoto sloupce.
Sloupce Ordinality
FOR ORDINALITY
možnost lze použít k počítání řádků počínaje 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;
Výsledek:
+------+---------+----------+--------+ | id | name | type | weight | +------+---------+----------+--------+ | 1 | Scratch | Cat | 8 | | 2 | Bruce | Kangaroo | 100 | | 3 | Hop | Kangaroo | 130 | +------+---------+----------+--------+
Kontrola existence cesty
Můžete použít EXISTS
klauzule pro kontrolu existence cesty. Pokud cesta v dokumentu JSON existuje, výsledek je 1
. Pokud neexistuje, 0
je vráceno.
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;
Výsledek:
+-------+----------+------------+ | name | type | has_weight | +-------+----------+------------+ | Punch | Kangaroo | 1 | | Snap | Cat | 1 | | Ruff | Dog | 0 | +-------+----------+------------+
Vnořené cesty
NESTED PATH
klauzule umožňuje pracovat s vnořenými dokumenty JSON. Když použijete tuto klauzuli, převede vnořené struktury JSON do více řádků.
Příklad:
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;
Výsledek:
+-------------------------+------+ | 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 | +-------------------------+------+
Zacházení s prázdnými cestami
ON EMPTY
klauzule určuje, co se udělá, když v dokumentu JSON chybí prvek určený vyhledávací cestou.
Příklad:
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;
Výsledek:
+-------+----------+--------+ | name | type | weight | +-------+----------+--------+ | Punch | Kangaroo | 200 | | Snap | Cat | 12 | | Ruff | N/A | NULL | +-------+----------+--------+
V tomto příkladu Ruff
nemá pole typu, a proto N/A
je vráceno. Je to proto, že jsem to uvedl v ON EMPTY
klauzule pro toto pole.
Řešení chyb
ON ERROR
klauzule určuje, co by se mělo udělat, pokud při pokusu o extrahování hodnoty z dokumentu dojde k chybě struktury JSON.
K chybě struktury JSON dochází pouze tehdy, když se pokusíte převést neskalární JSON (pole nebo objekt) na skalární hodnotu. Když se zobrazí ON ERROR
klauzule není přítomna, NULL ON ERROR
je naznačeno.
Zde je příklad zpracování chyby struktury 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;
Výsledek:
+-------------------------+-------+ | product | sizes | +-------------------------+-------+ | Left Handed Screwdriver | Oops! | | Long Weight | Oops! | | Bottomless Coffee Cup | None | +-------------------------+-------+
Zde jsem zadal řetězec (Oops!
) použít vždy, když dojde k chybě struktury JSON.
V tomto případě jsem také zahrnul ON EMPTY
doložka. To ukazuje, že obě ON ERROR
a ON EMPTY
klauzule lze použít ve stejném příkazu.
Je však důležité si uvědomit, že chyba převodu datového typu (například pokus o uložení neceločíselné hodnoty do celočíselného pole nebo zkrácení sloupce varchar) se nepovažuje za chybu JSON, a proto nespustí ON ERROR
doložka. Místo toho bude generovat varování.
Zde je příklad pro ilustraci toho, co mám na mysli:
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;
Výsledek:
+-------+------+ | name | type | +-------+------+ | Punch | 0 | | Snap | 0 | | Ruff | 0 | +-------+------+ 3 rows in set, 3 warnings (0.000 sec)
Ukážeme si varování:
SHOW WARNINGS;
Výsledek:
+---------+------+---------------------------------------------------------------------------------+ | 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 | +---------+------+---------------------------------------------------------------------------------+