O
->
e ->>
Os operadores foram introduzidos no SQLite versão 3.38.0, lançado em 22 de fevereiro de 2022. Ambos os operadores são usados para extrair subcomponentes do JSON. Mas há uma diferença sutil entre eles. A diferença
A diferença entre esses operadores é assim:
- O
->
operador sempre retorna um JSON representação do subcomponente especificado - O
->>
operador sempre retorna um SQL representação do subcomponente especificado
Exemplo
Aqui está um exemplo que ilustra a diferença entre esses dois operadores:
SELECT
'{ "name" : "Wag", "type" : "Dog" }' -> '$.type' AS "->",
'{ "name" : "Wag", "type" : "Dog" }' ->> '$.type' AS "->>";
Resultado:
+-------+-----+ | -> | ->> | +-------+-----+ | "Dog" | Dog | +-------+-----+
Podemos ver que
->
retornou o valor entre aspas duplas enquanto ->>
não. Isso porque
->
retornou uma representação JSON do valor e ->>
retornou uma representação SQL. Números
Aqui está um exemplo que usa números:
SELECT
'{ "age" : 10 }' -> '$.age' AS "->",
'{ "age" : 10 }' ->> '$.age' AS "->>";
Resultado:
+----+-----+ | -> | ->> | +----+-----+ | 10 | 10 | +----+-----+
Veja o que acontece quando usamos o
typeof()
função para obter o tipo SQL:SELECT
typeof('{ "age" : 10 }' -> '$.age') AS "->",
typeof('{ "age" : 10 }' ->> '$.age') AS "->>";
Resultado:
+------+---------+ | -> | ->> | +------+---------+ | text | integer | +------+---------+
No entanto, se usarmos
json_type()
, obteremos o tipo JSON:SELECT
json_type('{ "age" : 10 }' -> '$.age') AS "->",
json_type('{ "age" : 10 }' ->> '$.age') AS "->>";
Resultado:
+---------+---------+ | -> | ->> | +---------+---------+ | integer | integer | +---------+---------+
Aqui está um exemplo que usa um número real:
SELECT
typeof('{ "age" : 1.2 }' -> '$.age') AS "->",
typeof('{ "age" : 1.2 }' ->> '$.age') AS "->>";
Resultado:
+------+------+ | -> | ->> | +------+------+ | text | real | +------+------+
E com
json_type()
:SELECT
json_type('{ "age" : 1.2 }' -> '$.age') AS "->",
json_type('{ "age" : 1.2 }' ->> '$.age') AS "->>";
Resultado:
+------+------+ | -> | ->> | +------+------+ | real | real | +------+------+
Valores nulos
Se o documento JSON contiver
null
, então ->
retornará a representação JSON de null e ->>
simplesmente retornará um valor nulo. Aqui está um exemplo para demonstrar o que quero dizer:
SELECT
'{ "name" : "Wag", "type" : null }' -> '$.type' AS "->",
'{ "name" : "Wag", "type" : null }' ->> '$.type' AS "->>";
Resultado:
+------+-----+ | -> | ->> | +------+-----+ | null | | +------+-----+
Por padrão, a interface de linha de comando (CLI) do SQLite retorna a string vazia sempre que um valor nulo é retornado. Assim, podemos ver em nosso exemplo que
->
retornou o valor JSON real nulo, enquanto ->>
retornou um valor nulo real. Para demonstrar isso ainda mais, podemos definir nosso
.nullvalue
para algo diferente da string vazia:.nullvalue n/a
Agora vamos executar a consulta anterior novamente:
SELECT
'{ "name" : "Wag", "type" : null }' -> '$.type' AS "->",
'{ "name" : "Wag", "type" : null }' ->> '$.type' AS "->>";
Resultado:
+------+-----+ | -> | ->> | +------+-----+ | null | n/a | +------+-----+
Desta vez
n/a
foi gerado para o ->>
operador em vez da string vazia. E aqui está o que acontece quando passamos a saída para o
typeof()
e json_type()
funções:SELECT
typeof('{ "name" : "Wag", "type" : null }' -> '$.type') AS "->",
typeof('{ "name" : "Wag", "type" : null }' ->> '$.type') AS "->>";
SELECT
json_type('{ "name" : "Wag", "type" : null }' -> '$.type') AS "->",
json_type('{ "name" : "Wag", "type" : null }' ->> '$.type') AS "->>";
Resultado:
+------+------+ | -> | ->> | +------+------+ | text | null | +------+------+ +------+-----+ | -> | ->> | +------+-----+ | null | n/a | +------+-----+
Uma alternativa:json_extract()
Outra maneira de extrair valores de um documento JSON no SQLite é usar o
json_extract()
função. Esta função funciona um pouco diferente do ->
e ->>
em que o tipo de retorno depende do contexto. O
json_extract()
A função só retorna JSON se houver dois ou mais argumentos de caminho (porque o resultado é então uma matriz JSON) ou se o argumento de caminho único fizer referência a uma matriz ou objeto. Se houver apenas um argumento de caminho e esse caminho fizer referência a um JSON nulo ou uma string ou um valor numérico,
json_extract()
retorna o valor SQL NULL, TEXT, INTEGER ou REAL correspondente.