SQLite
 sql >> Base de données >  >> RDS >> SQLite

dans SQLite

Le -> et ->> Les opérateurs ont été introduits dans la version 3.38.0 de SQLite, qui a été publiée le 22 février 2022. Les deux opérateurs sont utilisés pour extraire des sous-composants de JSON. Mais il y a une différence subtile entre eux.

La différence

Voici la différence entre ces opérateurs :

  • Le -> l'opérateur renvoie toujours un JSON représentation du sous-composant spécifié
  • Le ->> l'opérateur renvoie toujours un SQL représentation du sous-composant spécifié

Exemple

Voici un exemple qui illustre la différence entre ces deux opérateurs :

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

Résultat :

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

Nous pouvons voir que -> a renvoyé la valeur entre guillemets alors que ->> non.

C'est parce que -> a renvoyé une représentation JSON de la valeur, et ->> a renvoyé une représentation SQL.

Numéros

Voici un exemple qui utilise des nombres :

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

Résultat :

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

Voici ce qui se passe lorsque nous utilisons le typeof() fonction pour obtenir le type SQL :

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

Résultat :

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

Cependant, si nous utilisons json_type() , nous obtiendrons le type JSON :

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

Résultat :

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

Voici un exemple qui utilise un nombre réel :

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

Résultat :

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

Et avec json_type() :

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

Résultat :

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

Valeurs nulles

Si le document JSON contient null , puis -> renverra la représentation JSON de null, et ->> renverra simplement une valeur nulle.

Voici un exemple pour illustrer ce que je veux dire :

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

Résultat :

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

Par défaut, l'interface de ligne de commande (CLI) SQLite renvoie la chaîne vide chaque fois qu'une valeur nulle est renvoyée. Nous pouvons donc voir dans notre exemple que -> a renvoyé la valeur JSON réelle nulle, alors que ->> a renvoyé une valeur nulle réelle.

Pour mieux le démontrer, nous pouvons définir notre .nullvalue à autre chose que la chaîne vide :

.nullvalue n/a

Maintenant, réexécutons la requête précédente :

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

Résultat :

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

Cette fois n/a a été généré pour le ->> opérateur au lieu de la chaîne vide.

Et voici ce qui se passe lorsque nous passons la sortie au typeof() et json_type() fonctions :

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 "->>";

Résultat :

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

Une alternative :json_extract()

Une autre façon d'extraire des valeurs d'un document JSON dans SQLite consiste à utiliser le json_extract() une fonction. Cette fonction fonctionne légèrement différemment du -> et ->> en ce que le type de retour dépend du contexte.

Le json_extract() La fonction ne renvoie JSON que s'il y a deux arguments de chemin ou plus (car le résultat est alors un tableau JSON) ou si l'argument de chemin unique fait référence à un tableau ou à un objet.

S'il n'y a qu'un seul argument de chemin et que ce chemin fait référence à un null JSON ou à une chaîne ou à une valeur numérique, alors json_extract() renvoie la valeur SQL NULL, TEXT, INTEGER ou REAL correspondante.