sql >> Base de Datos >  >> RDS >> SQLite

en SQLite

El -> y ->> Los operadores se introdujeron en SQLite versión 3.38.0, que se lanzó el 22 de febrero de 2022. Ambos operadores se utilizan para extraer subcomponentes de JSON. Pero hay una sutil diferencia entre ellos.

La diferencia

La diferencia entre estos operadores es la siguiente:

  • El -> el operador siempre devuelve un JSON representación del subcomponente especificado
  • El ->> operador siempre devuelve un SQL representación del subcomponente especificado

Ejemplo

Aquí hay un ejemplo que ilustra la diferencia entre estos dos operadores:

SELECT 
    '{ "name" : "Wag", "type" : "Dog" }' -> '$.type' AS "->",
    '{ "name" : "Wag", "type" : "Dog" }' ->> '$.type' AS "->>";

Resultado:

+-------+-----+
|  ->   | ->> |
+-------+-----+
| "Dog" | Dog |
+-------+-----+

Podemos ver que -> devolvió el valor entre comillas dobles mientras que ->> no lo hizo.

Eso es porque -> devolvió una representación JSON del valor y ->> devolvió una representación SQL.

Números

Aquí hay un ejemplo que usa números:

SELECT 
    '{ "age" : 10 }' -> '$.age' AS "->",
    '{ "age" : 10 }' ->> '$.age' AS "->>";

Resultado:

+----+-----+
| -> | ->> |
+----+-----+
| 10 | 10  |
+----+-----+

Esto es lo que sucede cuando usamos typeof() función para obtener el tipo SQL:

SELECT 
    typeof('{ "age" : 10 }' -> '$.age') AS "->",
    typeof('{ "age" : 10 }' ->> '$.age') AS "->>";

Resultado:

+------+---------+
|  ->  |   ->>   |
+------+---------+
| text | integer |
+------+---------+

Sin embargo, si usamos json_type() , obtendremos el tipo JSON:

SELECT 
    json_type('{ "age" : 10 }' -> '$.age') AS "->",
    json_type('{ "age" : 10 }' ->> '$.age') AS "->>";

Resultado:

+---------+---------+
|   ->    |   ->>   |
+---------+---------+
| integer | integer |
+---------+---------+

Aquí hay un ejemplo que usa un número real:

SELECT 
    typeof('{ "age" : 1.2 }' -> '$.age') AS "->",
    typeof('{ "age" : 1.2 }' ->> '$.age') AS "->>";

Resultado:

+------+------+
|  ->  | ->>  |
+------+------+
| text | real |
+------+------+

Y con json_type() :

SELECT 
    json_type('{ "age" : 1.2 }' -> '$.age') AS "->",
    json_type('{ "age" : 1.2 }' ->> '$.age') AS "->>";

Resultado:

+------+------+
|  ->  | ->>  |
+------+------+
| real | real |
+------+------+

Valores nulos

Si el documento JSON contiene null , luego -> devolverá la representación JSON de nulo y ->> simplemente devolverá un valor nulo.

Aquí hay un ejemplo para demostrar lo que quiero decir:

SELECT 
    '{ "name" : "Wag", "type" : null }' -> '$.type' AS "->",
    '{ "name" : "Wag", "type" : null }' ->> '$.type' AS "->>";

Resultado:

+------+-----+
|  ->  | ->> |
+------+-----+
| null |     |
+------+-----+

De forma predeterminada, la interfaz de línea de comandos (CLI) de SQLite devuelve la cadena vacía cada vez que se devuelve un valor nulo. Entonces podemos ver en nuestro ejemplo que -> devolvió el valor JSON real nulo, mientras que ->> devolvió un valor nulo real.

Para demostrar esto aún más, podemos configurar nuestro .nullvalue a algo que no sea la cadena vacía:

.nullvalue n/a

Ahora ejecutemos la consulta anterior de nuevo:

SELECT 
    '{ "name" : "Wag", "type" : null }' -> '$.type' AS "->",
    '{ "name" : "Wag", "type" : null }' ->> '$.type' AS "->>";

Resultado:

+------+-----+
|  ->  | ->> |
+------+-----+
| null | n/a |
+------+-----+

Esta vez n/a se emitió para el ->> operador en lugar de la cadena vacía.

Y esto es lo que sucede cuando pasamos la salida a typeof() y json_type() funciones:

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

Una alternativa:json_extract()

Otra forma de extraer valores de un documento JSON en SQLite es usar json_extract() función. Esta función funciona de forma ligeramente diferente a -> y ->> en que el tipo de retorno depende del contexto.

El json_extract() La función solo devuelve JSON si hay dos o más argumentos de ruta (porque el resultado es una matriz JSON) o si el argumento de ruta única hace referencia a una matriz u objeto.

Si solo hay un argumento de ruta y esa ruta hace referencia a un JSON nulo, una cadena o un valor numérico, entonces json_extract() devuelve el valor SQL NULL, TEXT, INTEGER o REAL correspondiente.