Il ->
e ->>
gli operatori sono stati introdotti in SQLite versione 3.38.0, rilasciata il 22 febbraio 2022. Entrambi gli operatori vengono utilizzati per estrarre i sottocomponenti di JSON. Ma c'è una sottile differenza tra loro.
La differenza
La differenza tra questi operatori è questa:
- Il
->
l'operatore restituisce sempre un JSON rappresentazione del sottocomponente specificato - Il
->>
l'operatore restituisce sempre un SQL rappresentazione del sottocomponente specificato
Esempio
Ecco un esempio che illustra la differenza tra questi due operatori:
SELECT
'{ "name" : "Wag", "type" : "Dog" }' -> '$.type' AS "->",
'{ "name" : "Wag", "type" : "Dog" }' ->> '$.type' AS "->>";
Risultato:
+-------+-----+ | -> | ->> | +-------+-----+ | "Dog" | Dog | +-------+-----+
Possiamo vedere che ->
ha restituito il valore racchiuso tra virgolette mentre ->>
no.
Questo perché ->
ha restituito una rappresentazione JSON del valore e ->>
ha restituito una rappresentazione SQL.
Numeri
Ecco un esempio che utilizza i numeri:
SELECT
'{ "age" : 10 }' -> '$.age' AS "->",
'{ "age" : 10 }' ->> '$.age' AS "->>";
Risultato:
+----+-----+ | -> | ->> | +----+-----+ | 10 | 10 | +----+-----+
Ecco cosa succede quando utilizziamo typeof()
funzione per ottenere il tipo SQL:
SELECT
typeof('{ "age" : 10 }' -> '$.age') AS "->",
typeof('{ "age" : 10 }' ->> '$.age') AS "->>";
Risultato:
+------+---------+ | -> | ->> | +------+---------+ | text | integer | +------+---------+
Tuttavia, se utilizziamo json_type()
, otterremo il tipo JSON:
SELECT
json_type('{ "age" : 10 }' -> '$.age') AS "->",
json_type('{ "age" : 10 }' ->> '$.age') AS "->>";
Risultato:
+---------+---------+ | -> | ->> | +---------+---------+ | integer | integer | +---------+---------+
Ecco un esempio che utilizza un numero reale:
SELECT
typeof('{ "age" : 1.2 }' -> '$.age') AS "->",
typeof('{ "age" : 1.2 }' ->> '$.age') AS "->>";
Risultato:
+------+------+ | -> | ->> | +------+------+ | text | real | +------+------+
E con json_type()
:
SELECT
json_type('{ "age" : 1.2 }' -> '$.age') AS "->",
json_type('{ "age" : 1.2 }' ->> '$.age') AS "->>";
Risultato:
+------+------+ | -> | ->> | +------+------+ | real | real | +------+------+
Valori Nulli
Se il documento JSON contiene null
, quindi ->
restituirà la rappresentazione JSON di null e ->>
restituirà semplicemente un valore nullo.
Ecco un esempio per dimostrare cosa intendo:
SELECT
'{ "name" : "Wag", "type" : null }' -> '$.type' AS "->",
'{ "name" : "Wag", "type" : null }' ->> '$.type' AS "->>";
Risultato:
+------+-----+ | -> | ->> | +------+-----+ | null | | +------+-----+
Per impostazione predefinita, l'interfaccia della riga di comando (CLI) di SQLite restituisce la stringa vuota ogni volta che viene restituito un valore null. Quindi possiamo vedere dal nostro esempio che ->
ha restituito il valore JSON effettivo null, mentre ->>
ha restituito un valore nullo effettivo.
Per dimostrarlo ulteriormente, possiamo impostare il nostro .nullvalue
a qualcosa di diverso dalla stringa vuota:
.nullvalue n/a
Ora eseguiamo nuovamente la query precedente:
SELECT
'{ "name" : "Wag", "type" : null }' -> '$.type' AS "->",
'{ "name" : "Wag", "type" : null }' ->> '$.type' AS "->>";
Risultato:
+------+-----+ | -> | ->> | +------+-----+ | null | n/a | +------+-----+
Questa volta n/a
è stato emesso per il ->>
operatore invece della stringa vuota.
Ed ecco cosa succede quando passiamo l'output a typeof()
e json_type()
funzioni:
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 "->>";
Risultato:
+------+------+ | -> | ->> | +------+------+ | text | null | +------+------+ +------+-----+ | -> | ->> | +------+-----+ | null | n/a | +------+-----+
Un'alternativa:json_extract()
Un altro modo per estrarre valori da un documento JSON in SQLite è utilizzare json_extract()
funzione. Questa funzione funziona in modo leggermente diverso da ->
e ->>
in quanto il tipo restituito dipende dal contesto.
Il json_extract()
La funzione restituisce JSON solo se sono presenti due o più argomenti del percorso (perché il risultato è quindi un array JSON) o se l'argomento del percorso singolo fa riferimento a un array o a un oggetto.
Se c'è un solo argomento di percorso e quel percorso fa riferimento a un valore JSON null o una stringa o un valore numerico, allora json_extract()
restituisce il valore SQL NULL, TEXT, INTEGER o REAL corrispondente.