No MariaDB,
JSON_TABLE()
é uma função interna que converte dados JSON em um formulário relacional. Em outras palavras, permite retornar um documento JSON como uma tabela.
O
JSON_TABLE()
A função foi introduzida no MariaDB 10.6.0. Sintaxe
A sintaxe fica assim:
JSON_TABLE(json_doc,
context_path COLUMNS (column_list)
) [AS] alias
Onde
column_list
fica assim:column[, column][, ...]
Onde
column
fica assim: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)
Onde
on_empty
fica assim:{NULL | DEFAULT string | ERROR} ON EMPTY
E
on_error
fica assim:{NULL | DEFAULT string | ERROR} ON ERROR
Exemplo
Aqui está um exemplo para demonstrar.
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;
Resultado:
+------+------+--------+ | name | type | weight | +------+------+--------+ | Wag | Dog | 20 | | Bark | Dog | 10 | | Meow | Cat | 7 | +------+------+--------+
Aqui, nomeamos cada coluna para a tabela, especificamos seu tipo de dados e, em seguida, especificamos o caminho do documento JSON que será aplicado a essa coluna.
Então, chamamos nossa primeira coluna de
name
, e mapeou o nó chamado name
do documento JSON para essa coluna. Colunas de Ordinalidade
O
FOR ORDINALITY
a opção pode ser usada para contar as linhas, começando em 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;
Resultado:
+------+---------+----------+--------+ | id | name | type | weight | +------+---------+----------+--------+ | 1 | Scratch | Cat | 8 | | 2 | Bruce | Kangaroo | 100 | | 3 | Hop | Kangaroo | 130 | +------+---------+----------+--------+
Verificando a existência de um caminho
Você pode usar o
EXISTS
cláusula para verificar a existência de um caminho. Se o caminho existir no documento JSON, o resultado será 1
. Se não existir, 0
é devolvido. 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;
Resultado:
+-------+----------+------------+ | name | type | has_weight | +-------+----------+------------+ | Punch | Kangaroo | 1 | | Snap | Cat | 1 | | Ruff | Dog | 0 | +-------+----------+------------+
Caminhos aninhados
O
NESTED PATH
A cláusula permite que você lide com documentos JSON aninhados. Quando você usa essa cláusula, ela converte estruturas JSON aninhadas em várias linhas. Exemplo:
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;
Resultado:
+-------------------------+------+ | 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 | +-------------------------+------+
Lidando com caminhos vazios
O
ON EMPTY
A cláusula especifica o que será feito quando o elemento especificado pelo caminho de pesquisa estiver ausente no documento JSON. Exemplo:
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;
Resultado:
+-------+----------+--------+ | name | type | weight | +-------+----------+--------+ | Punch | Kangaroo | 200 | | Snap | Cat | 12 | | Ruff | N/A | NULL | +-------+----------+--------+
Neste exemplo,
Ruff
não tem um campo de tipo e, portanto, N/A
é devolvido. Isso ocorre porque eu especifiquei que no ON EMPTY
cláusula para esse campo. Lidando com erros
O
ON ERROR
A cláusula especifica o que deve ser feito se ocorrer um erro de estrutura JSON ao tentar extrair o valor do documento. Um erro de estrutura JSON ocorre somente quando você tenta converter um JSON não escalar (matriz ou objeto) em um valor escalar. Quando o
ON ERROR
cláusula não está presente, NULL ON ERROR
está implícito. Aqui está um exemplo de como lidar com um erro de estrutura 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;
Resultado:
+-------------------------+-------+ | product | sizes | +-------------------------+-------+ | Left Handed Screwdriver | Oops! | | Long Weight | Oops! | | Bottomless Coffee Cup | None | +-------------------------+-------+
Aqui, especifiquei uma string (
Oops!
) para usar sempre que ocorrer um erro de estrutura JSON. Nesse caso, também incluí o
ON EMPTY
cláusula. Isso demonstra que tanto o ON ERROR
e o ON EMPTY
cláusula pode ser usada na mesma instrução. No entanto, é importante observar que um erro de conversão de tipo de dados (por exemplo, uma tentativa de armazenar um valor não inteiro em um campo inteiro ou uma coluna varchar truncada) não é considerado um erro JSON e, portanto, não acionará o
ON ERROR
cláusula. Em vez disso, produzirá avisos. Aqui está um exemplo para ilustrar o que quero dizer:
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;
Resultado:
+-------+------+ | name | type | +-------+------+ | Punch | 0 | | Snap | 0 | | Ruff | 0 | +-------+------+ 3 rows in set, 3 warnings (0.000 sec)
Vamos mostrar os avisos:
SHOW WARNINGS;
Resultado:
+---------+------+---------------------------------------------------------------------------------+ | 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 | +---------+------+---------------------------------------------------------------------------------+