Dvě z mnoha funkcí T-SQL dostupných na serveru SQL jsou JSON_QUERY()
a JSON_VALUE()
. Tyto funkce lze použít k extrahování dat z dokumentů JSON.
Jejich obecná syntaxe je podobná a na první pohled si můžete myslet, že dělají přesně to samé, ale nedělají. Při práci s JSON a SQL Serverem je určitě místo pro obě funkce.
Tento článek se zabývá rozdílem mezi JSON_QUERY()
a JSON_VALUE()
.
Rozdíl
Tyto dvě funkce mají mírně odlišné definice, mírně odlišnou syntaxi a jejich návratové hodnoty jsou mírně odlišné.
Definice
Zde je návod, jak jsou tyto dvě funkce definovány:
JSON_QUERY()
- Extrahuje objekt nebo pole z řetězce JSON.
JSON_VALUE()
- Extrahuje skalární hodnotu z řetězce JSON.
Rozdíl mezi těmito dvěma funkcemi je tedy to, co extrahují. Jeden extrahuje objekt nebo pole, druhý extrahuje skalární hodnotu.
Rozdíly v syntaxi
Další rozdíl je v syntaxi:
JSON_QUERY ( expression [ , path ] ) JSON_VALUE ( expression , path )
Podívejte se na JSON_QUERY()
syntax. Tyto hranaté závorky kolem path
argument znamená, že se jedná o volitelný argument. Je to proto, že tato funkce může v případě potřeby vrátit celý dokument JSON.
Při použití JSON_VALUE()
je však argument cesta povinným argumentem funkce. Při použití této funkce tedy musíte zadat oba argumenty.
Vrácené hodnoty
A ještě jeden rozdíl je v jejich návratových hodnotách.
JSON_QUERY()
vrátí fragment JSON typunvarchar(max)
JSON_VALUE()
vrátí jednou textovou hodnotu typunvarchar(4000)
Příklad 1 – Extrahování skalární hodnoty
Zde je příklad, který demonstruje rozdíl mezi těmito funkcemi při pokusu o extrakci skalární hodnoty.
SELECT JSON_VALUE('{"Name": "Homer"}', '$.Name') AS 'JSON_VALUE', JSON_QUERY('{"Name": "Homer"}', '$.Name') AS 'JSON_QUERY';
Výsledek:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | Homer | NULL | +--------------+--------------+
Obě funkce se tedy pokoušejí extrahovat stejnou hodnotu z dokumentu JSON, ale pouze jedna uspěje:JSON_VALUE()
. Je to proto, že hodnota, kterou se snaží extrahovat, je skalární hodnota. V podstatě skalární hodnota je jedna jednotka dat. Může to být řetězec textu nebo číslo. Ale nemůže to být objekt nebo pole.
Příklad 2 – Extrahování pole
V tomto příkladu se obě funkce pokusí extrahovat celé pole.
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';
Výsledek:
+--------------+----------------------------------------+ | JSON_VALUE | JSON_QUERY | |--------------+----------------------------------------| | NULL | ["Eating", "Sleeping", "Base Jumping"] | +--------------+----------------------------------------+
V tomto případě pouze JSON_QUERY()
funkce úspěšná.
Příklad 3 – Extrahování položky pole
Tento příklad je podobný předchozímu s tím rozdílem, že místo pokusu o extrahování celého pole chceme z pole pouze jednu položku.
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';
Výsledek:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | Base Jumping | NULL | +--------------+--------------+
Takže tentokrát JSON_VALUE()
je vítěz.
Příklad 4 – Extrahování objektu
Zkusme celý 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';
Výsledek:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | NULL | { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } | +--------------+--------------+
A JSON_QUERY()
vyhrává.
(Omluvte formátování, takto vrací můj nástroj příkazového řádku MSSQL výsledky).
Příklad 5 – Extrahujte celý dokument JSON
Zkusme celý dokument JSON.
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';
Výsledek:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | NULL | { "Cities": [ { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 }, { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } ] } | +--------------+--------------+
Takže JSON_QUERY()
je jediný, který může vrátit celý dokument.
Příklad 6 – Vynechání cesty
Dalším rozdílem mezi těmito dvěma funkcemi je to, že argument path je volitelný při použití JSON_QUERY()
. Pokud toto vynecháte, vrátí se celý dokument JSON.
Při použití JSON_VALUE()
nemůžete tento argument vynechat , protože je to povinný argument. To je pravděpodobně způsobeno tím, že funkce může vrátit pouze skalární hodnotu. Pokud by se první argument skládal pouze ze skalární hodnoty, nebyl by platný JSON.
Každopádně zde je příklad vynechání argumentu cesty z JSON_QUERY()
:
SELECT JSON_QUERY('{"Name": "Homer"}') AS 'Result';
Výsledek:
+-------------------+ | Result | |-------------------| | {"Name": "Homer"} | +-------------------+
A co se stane, když tento trik vyzkoušíme s JSON_VALUE()
:
SELECT JSON_VALUE('{"Name": "Homer"}') AS 'Result';
Výsledek:
Msg 174, Level 15, State 1, Line 1 The json_value function requires 2 argument(s).
Příklad 7 – Režim cesty
Když v předchozích příkladech funkce nemohla zpracovat zadanou cestu, vrátila NULL
. Je to proto, že všechny tyto příklady byly spuštěny v laxním režimu (výchozí režim).
Pokud bychom je spustili v přísném režimu, dostali bychom místo toho chybu. Chcete-li explicitně určit režim cesty, jednoduše jej přidejte před znak dolaru (a ponechte mezi nimi mezeru).
Zde je příklad toho, co se stane, když v přísném režimu zadáte neplatnou cestu:
SELECT JSON_VALUE('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_VALUE', JSON_QUERY('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_QUERY';
Výsledek:
Msg 13624, Level 16, State 2, Line 1 Object or array cannot be found in the specified JSON path.