W MariaDB, JSON_TABLE()
to wbudowana funkcja, która konwertuje dane JSON do postaci relacyjnej.
Innymi słowy, pozwala zwrócić dokument JSON jako tabelę.
JSON_TABLE()
funkcja została wprowadzona w MariaDB 10.6.0.
Składnia
Składnia wygląda tak:
JSON_TABLE(json_doc,
context_path COLUMNS (column_list)
) [AS] alias
Gdzie column_list
idzie tak:
column[, column][, ...]
Gdzie column
idzie tak:
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)
Gdzie on_empty
idzie tak:
{NULL | DEFAULT string | ERROR} ON EMPTY
I on_error
idzie tak:
{NULL | DEFAULT string | ERROR} ON ERROR
Przykład
Oto przykład do zademonstrowania.
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;
Wynik:
+------+------+--------+ | name | type | weight | +------+------+--------+ | Wag | Dog | 20 | | Bark | Dog | 10 | | Meow | Cat | 7 | +------+------+--------+
Tutaj nazywamy każdą kolumnę tabeli, określamy jej typ danych, a następnie określamy ścieżkę z dokumentu JSON, która będzie miała zastosowanie do tej kolumny.
Tak więc nazwaliśmy naszą pierwszą kolumnę name
, a następnie zmapowano węzeł o nazwie name
z dokumentu JSON do tej kolumny.
Kolumny porządkowe
FOR ORDINALITY
opcja może służyć do zliczania wierszy, zaczynając od 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;
Wynik:
+------+---------+----------+--------+ | id | name | type | weight | +------+---------+----------+--------+ | 1 | Scratch | Cat | 8 | | 2 | Bruce | Kangaroo | 100 | | 3 | Hop | Kangaroo | 130 | +------+---------+----------+--------+
Sprawdzanie istnienia ścieżki
Możesz użyć EXISTS
klauzula sprawdzająca istnienie ścieżki. Jeśli ścieżka istnieje w dokumencie JSON, wynikiem jest 1
. Jeśli nie istnieje, 0
jest zwracany.
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;
Wynik:
+-------+----------+------------+ | name | type | has_weight | +-------+----------+------------+ | Punch | Kangaroo | 1 | | Snap | Cat | 1 | | Ruff | Dog | 0 | +-------+----------+------------+
Ścieżki zagnieżdżone
NESTED PATH
klauzula pozwala radzić sobie z zagnieżdżonymi dokumentami JSON. Kiedy używasz tej klauzuli, konwertuje ona zagnieżdżone struktury JSON na wiele wierszy.
Przykład:
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;
Wynik:
+-------------------------+------+ | 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 | +-------------------------+------+
Radzenie sobie z pustymi ścieżkami
ON EMPTY
klauzula określa, co zostanie zrobione, gdy w dokumencie JSON brakuje elementu określonego przez ścieżkę wyszukiwania.
Przykład:
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;
Wynik:
+-------+----------+--------+ | name | type | weight | +-------+----------+--------+ | Punch | Kangaroo | 200 | | Snap | Cat | 12 | | Ruff | N/A | NULL | +-------+----------+--------+
W tym przykładzie Ruff
nie ma pola typu i dlatego N/A
jest zwracany. Dzieje się tak, ponieważ określiłem to w ON EMPTY
klauzula dla tego pola.
Radzenie sobie z błędami
ON ERROR
klauzula określa, co należy zrobić, jeśli podczas próby wyodrębnienia wartości z dokumentu wystąpi błąd struktury JSON.
Błąd struktury JSON występuje tylko podczas próby przekonwertowania wartości nieskalarnej JSON (tablicy lub obiektu) na wartość skalarną. Gdy ON ERROR
klauzula nie występuje, NULL ON ERROR
jest dorozumiana.
Oto przykład obsługi błędu 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;
Wynik:
+-------------------------+-------+ | product | sizes | +-------------------------+-------+ | Left Handed Screwdriver | Oops! | | Long Weight | Oops! | | Bottomless Coffee Cup | None | +-------------------------+-------+
Tutaj określiłem ciąg (Oops!
) do użycia, gdy wystąpi błąd struktury JSON.
W tym przypadku dołączyłem również ON EMPTY
klauzula. To pokazuje, że zarówno ON ERROR
i ON EMPTY
klauzula może być użyta w tej samej instrukcji.
Należy jednak pamiętać, że błąd konwersji typu danych (na przykład próba zapisania wartości niebędącej liczbą całkowitą w polu liczby całkowitej lub obcięcie kolumny varchar) nie jest uważany za błąd JSON i dlatego nie spowoduje wyzwolenia kodu ON ERROR
klauzula. Zamiast tego będzie generować ostrzeżenia.
Oto przykład ilustrujący, co mam na myśli:
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;
Wynik:
+-------+------+ | name | type | +-------+------+ | Punch | 0 | | Snap | 0 | | Ruff | 0 | +-------+------+ 3 rows in set, 3 warnings (0.000 sec)
Pokażmy ostrzeżenia:
SHOW WARNINGS;
Wynik:
+---------+------+---------------------------------------------------------------------------------+ | 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 | +---------+------+---------------------------------------------------------------------------------+