I SQLite er json_extract()
funktion udtrækker og returnerer en eller flere værdier fra veludformet JSON.
Vi sender JSON som et argument, når vi kalder funktionen, og den returnerer den/de relevante værdi/værdier.
Vi kan angive en eller flere stier, der skal udtrækkes fra JSON-dokumentet.
Syntaks
Syntaksen ser sådan ud:
json_extract(X,P1,P2,...)
Hvor X
repræsenterer JSON-dokumentet og P1,P2,...
er stier, som vi kan bruge til at udtrække bestemte dele af JSON-dokumentet.
Eksempler
Her er et grundlæggende eksempel for at demonstrere:
SELECT json_extract('{ "a" : 1 }', '$');
Resultat:
{"a":1}
Her specificerede jeg en sti til $
, som returnerer hele JSON-dokumentet.
Her er et eksempel med et større JSON-dokument:
SELECT json_extract('{
"dogs" : [
{ "name" : "Wag", "scores" : [ 7, 9 ] },
{ "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
{ "name" : "Woof", "scores" : [ 3, 2, 1 ] }
]
}',
'$'
);
Resultat:
{"dogs":[{"name":"Wag","scores":[7,9]},{"name":"Bark","scores":[3,4,8,7]},{"name":"Woof","scores":[3,2,1]}]}
Lad os ændre stien, så vi kun returnerer dogs
array:
SELECT json_extract('{
"dogs" : [
{ "name" : "Wag", "scores" : [ 7, 9 ] },
{ "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
{ "name" : "Woof", "scores" : [ 3, 2, 1 ] }
]
}',
'$.dogs'
);
Resultat:
[{"name":"Wag","scores":[7,9]},{"name":"Bark","scores":[3,4,8,7]},{"name":"Woof","scores":[3,2,1]}]
Lad os vælge et af elementerne i arrayet:
SELECT json_extract('{
"dogs" : [
{ "name" : "Wag", "scores" : [ 7, 9 ] },
{ "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
{ "name" : "Woof", "scores" : [ 3, 2, 1 ] }
]
}',
'$.dogs[1]'
);
Resultat:
{"name":"Bark","scores":[3,4,8,7]}
Arrays er nul-baserede, og derfor starter optællingen ved 0
. Derfor specificerede vi [1]
for at få det andet element i dogs
array, som tilfældigvis er et JSON-objekt.
Lad os gå dybere igen og returnere kun navnet på hunden på den position i arrayet:
SELECT json_extract('{
"dogs" : [
{ "name" : "Wag", "scores" : [ 7, 9 ] },
{ "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
{ "name" : "Woof", "scores" : [ 3, 2, 1 ] }
]
}',
'$.dogs[1].name'
);
Resultat:
Bark
Angiv flere stier
json_extract()
funktion giver os mulighed for at vælge flere stier:
SELECT json_extract('{
"dogs" : [
{ "name" : "Wag", "scores" : [ 7, 9 ] },
{ "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
{ "name" : "Woof", "scores" : [ 3, 2, 1 ] }
]
}',
'$.dogs[0].name',
'$.dogs[1].name',
'$.dogs[2].name'
);
Resultat:
["Wag","Bark","Woof"]
I dette tilfælde returnerede jeg navnene på alle hundene i dogs
array.
Alle hundenavne returneres i et array.
Valg af en ikke-eksisterende sti
Hvis vi peger på en sti, der ikke eksisterer, null
er returneret.
Lad os først indstille .nullvalue
til NULL
:
.nullvalue NULL
.nullvalue
dot-kommandoen giver os mulighed for at angive en streng, der vil blive brugt til at erstatte null-værdier. Det er en af flere måder, du kan erstatte null-værdier med en streng i SQLite. I dette tilfælde indstiller jeg den til NULL
. Nu vil alle null-værdier returnere NULL
i stedet for et tomt resultat.
Lad os nu kalde json_extract()
, men brug et andet argument, der peger på en ikke-eksisterende sti:
SELECT json_extract('{
"dogs" : [
{ "name" : "Wag", "scores" : [ 7, 9 ] },
{ "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
{ "name" : "Woof", "scores" : [ 3, 2, 1 ] }
]
}',
'$.cats'
);
Resultat:
NULL
Ugyldige stier
Vi får en fejl, hvis vores vej ikke er veludformet:
SELECT json_extract('{
"dogs" : [
{ "name" : "Wag", "scores" : [ 7, 9 ] },
{ "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
{ "name" : "Woof", "scores" : [ 3, 2, 1 ] }
]
}',
'dogs'
);
Resultat:
Runtime error: JSON path error near 'dogs'
I dette tilfælde glemte jeg at inkludere $.
forrest på stien.
Ugyldige JSON-dokumenter
Vi får også en fejl, JSON er ikke veludformet:
SELECT json_extract('{ "Dogs" : }',
'$'
);
Resultat:
Runtime error: malformed JSON
Denne gang fortæller fejlen os, at vores JSON er forkert udformet.
Returtyper
SQLite-dokumentationen angiver følgende:
Hvis der kun er angivet en enkelt sti P1, så er SQL-datatypen for resultatet NULL for en JSON null, INTEGER eller REAL for en JSON numerisk værdi, et INTEGER nul for en JSON falsk værdi, et INTEGER et for en JSON sand værdi, den deciterede tekst for en JSON-strengværdi og en tekstrepræsentation for JSON-objekt- og matrixværdier. Hvis der er flere sti-argumenter (P1, P2 og så videre), returnerer denne rutine SQLite-tekst, som er en velformet JSON-array, der indeholder de forskellige værdier.
MySQL-kompatibilitet
SQLite-dokumentationen advarer os også om en subtil inkompatibilitet mellem SQLite- og MySQL-implementeringerne af json_extract()
funktion.
Konkret står der:
MySQL-versionen af json_extract() returnerer altid JSON. SQLite-versionen af json_extract() returnerer kun JSON, hvis der er to eller flere PATH-argumenter (fordi resultatet så er et JSON-array), eller hvis det enkelte PATH-argument refererer til en matrix eller et objekt. I SQLite, hvis json_extract() kun har et enkelt PATH-argument, og den PATH refererer til en JSON-nul eller en streng eller en numerisk værdi, returnerer json_extract() den tilsvarende SQL NULL-, TEXT-, INTEGER- eller REAL-værdi.
Dybest set bliver denne forskel kun tydelig, når du får adgang til individuelle værdier i JSON'en, som er strenge eller NULL'er.