I MariaDB, JSON_TABLE()
är en inbyggd funktion som konverterar JSON-data till en relationsform.
Med andra ord låter den dig returnera ett JSON-dokument som en tabell.
JSON_TABLE()
funktion introducerades i MariaDB 10.6.0.
Syntax
Syntaxen ser ut så här:
JSON_TABLE(json_doc,
context_path COLUMNS (column_list)
) [AS] alias
Där column_list
går så här:
column[, column][, ...]
Där kolumn
går så här:
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)
Där on_empty
går så här:
{NULL | DEFAULT string | ERROR} ON EMPTY
Och on_error
går så här:
{NULL | DEFAULT string | ERROR} ON ERROR
Exempel
Här är ett exempel att visa.
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;
Resultat:
+------+------+--------+ | name | type | weight | +------+------+--------+ | Wag | Dog | 20 | | Bark | Dog | 10 | | Meow | Cat | 7 | +------+------+--------+
Här namnger vi varje kolumn för tabellen, anger dess datatyp och anger sedan sökvägen från JSON-dokumentet som ska gälla för den kolumnen.
Så vi kallade vår första kolumn name
, och mappade sedan noden som heter name
från JSON-dokumentet till den kolumnen.
Ordinalitetskolumner
FOR ORDINALITY
alternativet kan användas för att räkna raderna, med start från 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;
Resultat:
+------+---------+----------+--------+ | id | name | type | weight | +------+---------+----------+--------+ | 1 | Scratch | Cat | 8 | | 2 | Bruce | Kangaroo | 100 | | 3 | Hop | Kangaroo | 130 | +------+---------+----------+--------+
Kontrollera att det finns en sökväg
Du kan använda EXISTS
klausul för att kontrollera om det finns en sökväg. Om sökvägen finns i JSON-dokumentet är resultatet 1
. Om det inte finns, 0
returneras.
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;
Resultat:
+-------+----------+------------+ | name | type | has_weight | +-------+----------+------------+ | Punch | Kangaroo | 1 | | Snap | Cat | 1 | | Ruff | Dog | 0 | +-------+----------+------------+
Inkapslade vägar
Den NESTED PATH
sats låter dig hantera kapslade JSON-dokument. När du använder den här satsen konverterar den kapslade JSON-strukturer till flera rader.
Exempel:
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;
Resultat:
+-------------------------+------+ | 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 | +-------------------------+------+
Hantera tomma vägar
ON EMPTY
sats anger vad som kommer att göras när elementet som anges av sökvägen saknas i JSON-dokumentet.
Exempel:
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;
Resultat:
+-------+----------+--------+ | name | type | weight | +-------+----------+--------+ | Punch | Kangaroo | 200 | | Snap | Cat | 12 | | Ruff | N/A | NULL | +-------+----------+--------+
I det här exemplet, Ruff
har inget typfält och därför N/A
returneras. Detta beror på att jag angav det i ON EMPTY
klausul för det fältet.
Hantera fel
ON ERROR
sats anger vad som ska göras om ett JSON-strukturfel uppstår när man försöker extrahera värdet från dokumentet.
Ett JSON-strukturfel uppstår endast när du försöker konvertera en icke-skalär JSON (matris eller objekt) till ett skalärt värde. När ON ERROR
klausul finns inte, NULL ON ERROR
är underförstått.
Här är ett exempel på att hantera ett JSON-strukturfel:
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;
Resultat:
+-------------------------+-------+ | product | sizes | +-------------------------+-------+ | Left Handed Screwdriver | Oops! | | Long Weight | Oops! | | Bottomless Coffee Cup | None | +-------------------------+-------+
Här angav jag en sträng (Hoppsan!
) att använda när ett JSON-strukturfel inträffade.
I det här fallet inkluderade jag även ON EMPTY
klausul. Detta visar att både ON ERROR
och ON EMPTY
sats kan användas i samma sats.
Det är dock viktigt att notera att ett datatypkonverteringsfel (till exempel ett försök att lagra ett icke-heltalsvärde i ett heltalsfält eller en varchar kolumn som trunkeras) inte anses vara ett JSON-fel och kommer därför inte att utlösa
Här är ett exempel för att illustrera vad jag menar:
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;
Resultat:
+-------+------+ | name | type | +-------+------+ | Punch | 0 | | Snap | 0 | | Ruff | 0 | +-------+------+ 3 rows in set, 3 warnings (0.000 sec)
Låt oss visa varningarna:
SHOW WARNINGS;
Resultat:
+---------+------+---------------------------------------------------------------------------------+ | 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 | +---------+------+---------------------------------------------------------------------------------+