MariaDB
 sql >> Base de Dados >  >> RDS >> MariaDB

MariaDB JSON_TABLE() Explicado


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      |
+---------+------+---------------------------------------------------------------------------------+