Dwie z wielu funkcji T-SQL dostępnych w SQL Server to JSON_QUERY()
i JSON_VALUE()
. Tych funkcji można używać do wyodrębniania danych z dokumentów JSON.
Ich ogólna składnia jest podobna i na pierwszy rzut oka możesz pomyśleć, że robią dokładnie to samo, ale tak nie jest. Podczas pracy z JSON i SQL Server zdecydowanie jest miejsce dla obu funkcji.
W tym artykule przyjrzymy się różnicy między JSON_QUERY()
i JSON_VALUE()
.
Różnica
Te dwie funkcje mają nieco inne definicje, nieco inną składnię, a ich wartości zwracane są nieco inne.
Definicje
Oto jak zdefiniowano te dwie funkcje:
JSON_QUERY()
- Wyodrębnia obiekt lub tablicę z ciągu JSON.
JSON_VALUE()
- Wyodrębnia wartość skalarną z ciągu JSON.
Tak więc różnica między tymi dwiema funkcjami polega na tym, co wyodrębniają. Jeden wyodrębnia obiekt lub tablicę, drugi wyodrębnia wartość skalarną.
Różnice składni
Kolejna różnica dotyczy składni:
JSON_QUERY ( expression [ , path ] ) JSON_VALUE ( expression , path )
Spójrz na JSON_QUERY()
składnia. Te nawiasy kwadratowe wokół path
argument oznacza, że jest to argument opcjonalny. Dzieje się tak, ponieważ ta funkcja może zwrócić cały dokument JSON, jeśli jest to wymagane.
Jednak argument ścieżki jest wymagany podczas korzystania z JSON_VALUE()
funkcjonować. Musisz więc podać oba argumenty podczas korzystania z tej funkcji.
Zwracane wartości
I jeszcze jedna różnica dotyczy ich wartości zwracanych.
JSON_QUERY()
zwraca fragment JSON typunvarchar(max)
JSON_VALUE()
zwraca pojedynczą wartość tekstową typunvarchar(4000)
Przykład 1 – Wyodrębnij wartość skalarną
Oto przykład pokazujący różnicę między tymi funkcjami podczas próby wyodrębnienia wartości skalarnej.
SELECT JSON_VALUE('{"Name": "Homer"}', '$.Name') AS 'JSON_VALUE', JSON_QUERY('{"Name": "Homer"}', '$.Name') AS 'JSON_QUERY';
Wynik:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | Homer | NULL | +--------------+--------------+
Tak więc obie funkcje próbują wyodrębnić tę samą wartość z dokumentu JSON, ale tylko jedna się udaje:JSON_VALUE()
. Dzieje się tak, ponieważ wartość, którą próbują wyodrębnić, jest wartością skalarną. Zasadniczo wartość skalarna to jedna jednostka danych. Może to być ciąg tekstu lub liczba. Ale nie może to być obiekt ani tablica.
Przykład 2 – Wyodrębnij tablicę
W tym przykładzie obie funkcje próbują wyodrębnić całą tablicę.
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';
Wynik:
+--------------+----------------------------------------+ | JSON_VALUE | JSON_QUERY | |--------------+----------------------------------------| | NULL | ["Eating", "Sleeping", "Base Jumping"] | +--------------+----------------------------------------+
W tym przypadku tylko JSON_QUERY()
funkcja się powiedzie.
Przykład 3 – wyodrębnianie elementu tablicy
Ten przykład jest podobny do poprzedniego, z tą różnicą, że zamiast próbować wyodrębnić całą tablicę, potrzebujemy tylko jednego elementu z tablicy.
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';
Wynik:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | Base Jumping | NULL | +--------------+--------------+
Więc tym razem JSON_VALUE()
jest zwycięzcą.
Przykład 4 – Wyodrębnij obiekt
Spróbujmy dla całego obiektu.
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';
Wynik:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | NULL | { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } | +--------------+--------------+
I JSON_QUERY()
wygrywa.
(Przepraszam za formatowanie, tak moje narzędzie wiersza poleceń MSSQL zwraca wyniki).
Przykład 5 – Wyodrębnij cały dokument JSON
Spróbujmy dla całego dokumentu 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';
Wynik:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | NULL | { "Cities": [ { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 }, { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } ] } | +--------------+--------------+
Więc JSON_QUERY()
jest jedynym, który może zwrócić cały dokument.
Przykład 6 – Pomiń ścieżkę
Kolejną różnicą między tymi dwiema funkcjami jest to, że argument path jest opcjonalny podczas korzystania z JSON_QUERY()
. Jeśli to pominiesz, zwrócony zostanie cały dokument JSON.
Nie możesz pominąć tego argumentu przy użyciu JSON_VALUE()
, ponieważ jest to wymagany argument. Wynika to prawdopodobnie z faktu, że funkcja może zwrócić tylko wartość skalarną. Gdyby pierwszy argument składał się tylko z wartości skalarnej, nie byłby to prawidłowy JSON.
W każdym razie, oto przykład pominięcia argumentu ścieżki z JSON_QUERY()
:
SELECT JSON_QUERY('{"Name": "Homer"}') AS 'Result';
Wynik:
+-------------------+ | Result | |-------------------| | {"Name": "Homer"} | +-------------------+
A oto, co się stanie, jeśli spróbujemy tej sztuczki z JSON_VALUE()
:
SELECT JSON_VALUE('{"Name": "Homer"}') AS 'Result';
Wynik:
Msg 174, Level 15, State 1, Line 1 The json_value function requires 2 argument(s).
Przykład 7 – Tryb ścieżki
We wcześniejszych przykładach, gdy funkcja nie mogła obsłużyć podanej ścieżki, zwracała NULL
. Dzieje się tak, ponieważ wszystkie te przykłady zostały uruchomione w trybie lax (tryb domyślny).
Gdybyśmy uruchomili je w trybie ścisłym, zamiast tego otrzymalibyśmy błąd. Aby wyraźnie określić tryb ścieżki, po prostu dodaj go przed znakiem dolara (i zostaw między nimi spację).
Oto przykład tego, co się dzieje, gdy podasz nieprawidłową ścieżkę w trybie ścisłym:
SELECT JSON_VALUE('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_VALUE', JSON_QUERY('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_QUERY';
Wynik:
Msg 13624, Level 16, State 2, Line 1 Object or array cannot be found in the specified JSON path.