Twee van de vele T-SQL-functies die beschikbaar zijn in SQL Server zijn JSON_QUERY()
en JSON_VALUE()
. Deze functies kunnen worden gebruikt om gegevens uit JSON-documenten te extraheren.
Hun algemene syntaxis is vergelijkbaar, en op het eerste gezicht zou je kunnen denken dat ze precies hetzelfde doen, maar dat doen ze niet. Er is zeker plaats voor beide functies bij het werken met JSON en SQL Server.
Dit artikel gaat in op het verschil tussen JSON_QUERY()
en JSON_VALUE()
.
Het verschil
Deze twee functies hebben iets verschillende definities, een iets andere syntaxis en hun retourwaarden zijn iets anders.
Definities
Zo worden de twee functies gedefinieerd:
JSON_QUERY()
- Haalt een object of een array uit een JSON-tekenreeks.
JSON_VALUE()
- Haalt een scalaire waarde uit een JSON-tekenreeks.
Dus het verschil tussen deze twee functies is wat ze extraheren. De ene extraheert een object of een array, de andere extraheert een scalaire waarde.
Syntaxisverschillen
Een ander verschil zit in de syntaxis:
JSON_QUERY ( expression [ , path ] ) JSON_VALUE ( expression , path )
Kijk naar de JSON_QUERY()
syntaxis. Die vierkante haken rond het path
argument betekent dat het een optioneel argument is. Dat komt omdat deze functie indien nodig een heel JSON-document kan retourneren.
Het padargument is echter een verplicht argument bij gebruik van de JSON_VALUE()
functie. U moet dus beide argumenten opgeven wanneer u deze functie gebruikt.
Retourwaarden
En nog een verschil zit in hun retourwaarden.
JSON_QUERY()
retourneert een JSON-fragment van het typenvarchar(max)
JSON_VALUE()
retourneert een enkele tekstwaarde van het typenvarchar(4000)
Voorbeeld 1 – Een scalaire waarde extraheren
Hier is een voorbeeld om het verschil tussen deze functies te demonstreren bij het extraheren van een scalaire waarde.
SELECT JSON_VALUE('{"Name": "Homer"}', '$.Name') AS 'JSON_VALUE', JSON_QUERY('{"Name": "Homer"}', '$.Name') AS 'JSON_QUERY';
Resultaat:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | Homer | NULL | +--------------+--------------+
Dus beide functies proberen dezelfde waarde uit het JSON-document te halen, maar slechts één slaagt:JSON_VALUE()
. Dit komt omdat de waarde die ze proberen te extraheren een scalaire waarde is. Kortom, een scalaire waarde is één gegevenseenheid. Dit kan een tekstreeks of een cijfer zijn. Maar het kan geen object of array zijn.
Voorbeeld 2 – Een array extraheren
In dit voorbeeld proberen beide functies een hele array te extraheren.
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';
Resultaat:
+--------------+----------------------------------------+ | JSON_VALUE | JSON_QUERY | |--------------+----------------------------------------| | NULL | ["Eating", "Sleeping", "Base Jumping"] | +--------------+----------------------------------------+
In dit geval is alleen de JSON_QUERY()
functie slaagt.
Voorbeeld 3 – Een array-item extraheren
Dit voorbeeld is vergelijkbaar met het vorige, behalve dat we in plaats van te proberen de hele array te extraheren, maar één item uit de array willen.
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';
Resultaat:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | Base Jumping | NULL | +--------------+--------------+
Dus deze keer JSON_VALUE()
is de winnaar.
Voorbeeld 4 – Een object extraheren
Laten we een heel object proberen.
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';
Resultaat:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | NULL | { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } | +--------------+--------------+
En JSON_QUERY()
wint.
(Excuseer de opmaak, dit is hoe mijn MSSQL-opdrachtregelprogramma de resultaten retourneert).
Voorbeeld 5 – Pak het hele JSON-document uit
Laten we het hele JSON-document proberen.
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';
Resultaat:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | NULL | { "Cities": [ { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 }, { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } ] } | +--------------+--------------+
Dus JSON_QUERY()
is de enige die het hele document kan retourneren.
Voorbeeld 6 – Weglaten van het pad
Een ander verschil tussen deze twee functies is dat het padargument optioneel is bij gebruik van JSON_QUERY()
. Als u dit weglaat, wordt het hele JSON-document geretourneerd.
U kunt dit argument niet weglaten bij gebruik van JSON_VALUE()
, omdat het een verplicht argument is. Dit is waarschijnlijk te wijten aan het feit dat de functie alleen een scalaire waarde kan retourneren. Als het eerste argument alleen uit een scalaire waarde zou bestaan, zou het geen geldige JSON zijn.
Hoe dan ook, hier is een voorbeeld van het weglaten van het padargument van JSON_QUERY()
:
SELECT JSON_QUERY('{"Name": "Homer"}') AS 'Result';
Resultaat:
+-------------------+ | Result | |-------------------| | {"Name": "Homer"} | +-------------------+
En dit is wat er gebeurt als we die truc proberen met JSON_VALUE()
:
SELECT JSON_VALUE('{"Name": "Homer"}') AS 'Result';
Resultaat:
Msg 174, Level 15, State 1, Line 1 The json_value function requires 2 argument(s).
Voorbeeld 7 – Padmodus
In de eerdere voorbeelden, wanneer een functie het opgegeven pad niet aankon, retourneerde deze NULL
. Dit komt omdat al deze voorbeelden werden uitgevoerd in de lax-modus (de standaardmodus).
Als we ze in de strikte modus hadden uitgevoerd, zouden we in plaats daarvan een foutmelding hebben gekregen. Om de padmodus expliciet te specificeren, voegt u deze toe voor het dollarteken (en laat u een spatie ertussen).
Hier is een voorbeeld van wat er gebeurt als je een ongeldig pad opgeeft in de strikte modus:
SELECT JSON_VALUE('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_VALUE', JSON_QUERY('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_QUERY';
Resultaat:
Msg 13624, Level 16, State 2, Line 1 Object or array cannot be found in the specified JSON path.