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.