В MariaDB, JSON_TABLE()
е вградена функция, която преобразува JSON данните в релационна форма.
С други думи, той ви позволява да върнете JSON документ като таблица.
JSON_TABLE()
функцията беше въведена в MariaDB 10.6.0.
Синтаксис
Синтаксисът е така:
JSON_TABLE(json_doc,
context_path COLUMNS (column_list)
) [AS] alias
Където column_list
става така:
column[, column][, ...]
Където column
става така:
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)
Където on_empty
става така:
{NULL | DEFAULT string | ERROR} ON EMPTY
И on_error
става така:
{NULL | DEFAULT string | ERROR} ON ERROR
Пример
Ето пример за демонстрация.
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;
Резултат:
+------+------+-------+| име | тип | тегло |+------+------+-------+| Размахване | Куче | 20 || Кора | Куче | 10 || Мяу | Котка | 7 |+------+------+-------+
Тук ние именуваме всяка колона за таблицата, указваме нейния тип данни и след това указваме пътя от JSON документа, който ще се прилага към тази колона.
И така, нарекохме първата колона name
, и след това картографира възела, наречен name
от JSON документа към тази колона.
Колони за редовност
FOR ORDINALITY
опцията може да се използва за преброяване на редовете, започвайки от 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;
Резултат:
+------+--------+---------+-------+| ID | име | тип | тегло |+------+---------+---------+-------+| 1 | Надраскване | Котка | 8 || 2 | Брус | Кенгуру | 100 || 3 | Хоп | Кенгуру | 130 |+------+--------+---------+-------+
Проверка на съществуването на път
Можете да използвате EXISTS
клауза за проверка за съществуването на път. Ако пътят съществува в JSON документа, резултатът е 1
. Ако не съществува, 0
се връща.
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;
Резултат:
+-------+----------+------------+| име | тип | има_тегло |+-------+----------+-----------+| Удар | Кенгуру | 1 || Снимане | Котка | 1 || Руф | Куче | 0 |+-------+----------+-----------+
Вложени пътища
NESTED PATH
клаузата ви позволява да работите с вложени JSON документи. Когато използвате тази клауза, тя преобразува вложените 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',
NESTED PATH '$.sizes[*]' columns (
size VARCHAR(2) PATH '$'
)
)
) AS json_table;
Резултат:
+------------------------+-----+| продукт | размер |+-------------------+------+| Отвертка с лява ръка | S || Отвертка с лява ръка | M || Отвертка с лява ръка | L || Дълго тегло | S || Дълго тегло | L || Дълго тегло | XL || Бездънна чаша за кафе | NULL |+------------------------+-----+
Справяне с празни пътища
ON EMPTY
Клаузата указва какво ще се направи, когато елементът, посочен от пътя за търсене, липсва в документа JSON.
Пример:
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;
Резултат:
<пред>+-------+---------+-------+| име | тип | тегло |+-------+----------+-------+| Удар | Кенгуру | 200 || Снимане | Котка | 12 || Руф | N/A | NULL |+-------+----------+-------+
В този пример Ruff
няма поле за тип и следователно N/A
се връща. Това е така, защото посочих това в ON EMPTY
клауза за това поле.
Справяне с грешки
ON ERROR
клаузата указва какво трябва да се направи, ако възникне грешка в структурата на JSON при опит за извличане на стойността от документа.
Грешка в структурата на JSON възниква само когато се опитате да преобразувате нескаларен JSON (масив или обект) в скаларна стойност. Когато ON ERROR
клауза не е налице, NULL ON ERROR
се подразбира.
Ето пример за обработка на грешка в структурата на 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;
Резултат:
+------------------------+-------+| продукт | размери |+------------------------+-------+| Отвертка с лява ръка | Опа! || Дълго тегло | Опа! || Бездънна чаша за кафе | Няма |+------------------------+-------+
Тук посочих низ (Oops!
), за да се използва всеки път, когато възникне грешка в структурата на JSON.
В този случай включих и ON EMPTY
клауза. Това показва, че и двете ON ERROR
и ON EMPTY
клаузата може да се използва в същото изявление.
Важно е обаче да се отбележи, че грешка при преобразуване на типа данни (например опит за съхраняване на нецелочислена стойност в целочислено поле или колона varchar, която се съкращава) не се счита за грешка в JSON и така няма да задейства ON ERROR
клауза. Вместо това ще извежда предупреждения.
Ето един пример, за да илюстрирам какво имам предвид:
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;
Резултат:
+-------+------+| име | тип |+-------+-----+| Удар | 0 || Снимане | 0 || Руф | 0 |+-------+------+3 реда в комплект, 3 предупреждения (0,000 сек.)
Нека покажем предупрежденията:
SHOW WARNINGS;
Резултат:
+--------+------+---------------------------- -------------------------------------------------- --+| Ниво | Код | Съобщение |+--------+------+------------------------------ -------------------------------------------------- -+| Предупреждение | 1366 | Неправилна стойност на цяло число:'Кенгуру' за колона ``.`(временна)`.`тип` на ред 1 || Предупреждение | 1366 | Неправилна стойност на цяло число:'Котка' за колона ``.`(временна)`.`тип` на ред 2 || Предупреждение | 1366 | Неправилна стойност на цяло число:'Куче' за колона ``.`(временен)`.`тип` на ред 3 |+---------+------+------- -------------------------------------------------- ------------------------+