To af de mange T-SQL-funktioner, der er tilgængelige i SQL Server, er JSON_QUERY()
og JSON_VALUE()
. Disse funktioner kan bruges til at udtrække data fra JSON-dokumenter.
Deres generelle syntaks er ens, og ved første øjekast tror du måske, de gør præcis det samme, men det gør de ikke. Der er bestemt plads til begge funktioner, når du arbejder med JSON og SQL Server.
Denne artikel ser på forskellen mellem JSON_QUERY()
og JSON_VALUE()
.
Forskellen
Disse to funktioner har lidt forskellige definitioner, en lidt anderledes syntaks, og deres returværdier er lidt forskellige.
Definitioner
Sådan defineres de to funktioner:
JSON_QUERY()
- Udtrækker et objekt eller en matrix fra en JSON-streng.
JSON_VALUE()
- Udtrækker en skalarværdi fra en JSON-streng.
Så forskellen mellem disse to funktioner er, hvad de udvinder. Den ene udtrækker et objekt eller en matrix, den anden udtrækker en skalarværdi.
Syntaksforskelle
En anden forskel er i syntaksen:
JSON_QUERY ( expression [ , path ] ) JSON_VALUE ( expression , path )
Se på JSON_QUERY()
syntaks. Disse firkantede parenteser omkring path
argument betyder, at det er et valgfrit argument. Det skyldes, at denne funktion kan returnere et helt JSON-dokument, hvis det kræves.
Stiargumentet er dog et påkrævet argument, når du bruger JSON_VALUE()
fungere. Så du skal angive begge argumenter, når du bruger denne funktion.
Returværdier
Og endnu en forskel er deres afkastværdier.
JSON_QUERY()
returnerer et JSON-fragment af typennvarchar(max)
JSON_VALUE()
returnerer en enkelt tekstværdi af typennvarchar(4000)
Eksempel 1 – Udtræk en skalær værdi
Her er et eksempel for at demonstrere forskellen mellem disse funktioner, når du forsøger at udtrække en skalarværdi.
SELECT JSON_VALUE('{"Name": "Homer"}', '$.Name') AS 'JSON_VALUE', JSON_QUERY('{"Name": "Homer"}', '$.Name') AS 'JSON_QUERY';
Resultat:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | Homer | NULL | +--------------+--------------+
Så begge funktioner forsøger at udtrække den samme værdi fra JSON-dokumentet, men kun den ene lykkes:JSON_VALUE()
. Dette skyldes, at den værdi, de forsøger at udvinde, er en skalær værdi. Dybest set en skalær værdi er en dataenhed. Det kan være en tekststreng eller et tal. Men det kan ikke være et objekt eller en matrix.
Eksempel 2 – Udpak et array
I dette eksempel forsøger begge funktioner at udtrække et helt array.
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Suspect": { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } }' SELECT JSON_VALUE(@data,'$.Suspect.Hobbies') AS 'JSON_VALUE', JSON_QUERY(@data,'$.Suspect.Hobbies') AS 'JSON_QUERY';
Resultat:
+--------------+----------------------------------------+ | JSON_VALUE | JSON_QUERY | |--------------+----------------------------------------| | NULL | ["Eating", "Sleeping", "Base Jumping"] | +--------------+----------------------------------------+
I dette tilfælde er det kun JSON_QUERY()
funktionen lykkes.
Eksempel 3 – Udpak et array-element
Dette eksempel ligner det forrige, bortset fra at i stedet for at prøve at udtrække hele arrayet, vil vi kun have et enkelt element fra arrayet.
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Suspect": { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } }' SELECT JSON_VALUE(@data,'$.Suspect.Hobbies[2]') AS 'JSON_VALUE', JSON_QUERY(@data,'$.Suspect.Hobbies[2]') AS 'JSON_QUERY';
Resultat:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | Base Jumping | NULL | +--------------+--------------+
Så denne gang JSON_VALUE()
er vinderen.
Eksempel 4 – Udpak et objekt
Lad os prøve et helt objekt.
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Suspect": { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } }' SELECT JSON_VALUE(@data,'$.Suspect') AS 'JSON_VALUE', JSON_QUERY(@data,'$.Suspect') AS 'JSON_QUERY';
Resultat:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | NULL | { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } | +--------------+--------------+
Og JSON_QUERY()
vinder.
(Undskyld formateringen, det er sådan mit MSSQL kommandolinjeværktøj returnerer resultaterne).
Eksempel 5 – Udpak hele JSON-dokumentet
Lad os prøve hele JSON-dokumentet.
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Cities": [ { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 }, { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } ] }' SELECT JSON_VALUE(@data, '$') AS 'JSON_VALUE', JSON_QUERY(@data, '$') AS 'JSON_QUERY';
Resultat:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | NULL | { "Cities": [ { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 }, { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } ] } | +--------------+--------------+
Så JSON_QUERY()
er den eneste, der kan returnere hele dokumentet.
Eksempel 6 – Udelad stien
En anden forskel mellem disse to funktioner er, at sti-argumentet er valgfrit, når du bruger JSON_QUERY()
. Hvis du udelader dette, returneres hele JSON-dokumentet.
Du kan ikke udelade dette argument, når du bruger JSON_VALUE()
, da det er et påkrævet argument. Dette skyldes sandsynligvis, at funktionen kun kan returnere en skalarværdi. Hvis det første argument kun bestod af en skalarværdi, ville det ikke være gyldig JSON.
Uanset hvad, her er et eksempel på udeladelse af sti-argumentet fra JSON_QUERY()
:
SELECT JSON_QUERY('{"Name": "Homer"}') AS 'Result';
Resultat:
+-------------------+ | Result | |-------------------| | {"Name": "Homer"} | +-------------------+
Og her er, hvad der sker, hvis vi prøver det trick med JSON_VALUE()
:
SELECT JSON_VALUE('{"Name": "Homer"}') AS 'Result';
Resultat:
Msg 174, Level 15, State 1, Line 1 The json_value function requires 2 argument(s).
Eksempel 7 – Stitilstand
I de tidligere eksempler, når en funktion ikke kunne håndtere den angivne sti, returnerede den NULL
. Dette skyldes, at alle disse eksempler blev kørt i slap tilstand (standardtilstanden).
Hvis vi havde kørt dem i streng tilstand, ville vi have modtaget en fejl i stedet for. For eksplicit at angive stitilstanden skal du blot tilføje den før dollartegnet (og efterlade et mellemrum mellem dem).
Her er et eksempel på, hvad der sker, når du angiver en ugyldig sti, mens du er i streng tilstand:
SELECT JSON_VALUE('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_VALUE', JSON_QUERY('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_QUERY';
Resultat:
Msg 13624, Level 16, State 2, Line 1 Object or array cannot be found in the specified JSON path.