Две от многото T-SQL функции, налични в SQL Server, са JSON_QUERY()
и JSON_VALUE()
. Тези функции могат да се използват за извличане на данни от JSON документи.
Общият им синтаксис е подобен и на пръв поглед може да си помислите, че правят абсолютно същото нещо, но не го правят. Определено има място и за двете функции, когато работите с JSON и SQL Server.
Тази статия разглежда разликата между JSON_QUERY()
и JSON_VALUE()
.
Разликата
Тези две функции имат малко различни дефиниции, малко по-различен синтаксис и връщаните им стойности са малко по-различни.
Дефиниции
Ето как се дефинират двете функции:
JSON_QUERY()
- Извлича обект или масив от JSON низ.
JSON_VALUE()
- Извлича скаларна стойност от JSON низ.
Така че разликата между тези две функции е това, което те извличат. Единият извлича обект или масив, другият извлича скаларна стойност.
Разлики в синтаксиса
Друга разлика е в синтаксиса:
JSON_QUERY ( израз [ , път ] )JSON_VALUE ( израз , път )
Вижте JSON_QUERY()
синтаксис. Тези квадратни скоби около path
аргумент означава, че това е незадължителен аргумент. Това е така, защото тази функция може да върне цял JSON документ, ако е необходимо.
Аргументът на пътя обаче е задължителен аргумент при използване на JSON_VALUE()
функция. Така че трябва да предоставите и двата аргумента, когато използвате тази функция.
Върнати стойности
И още една разлика е във върнатите им стойности.
JSON_QUERY()
връща JSON фрагмент от типnvarchar(max)
JSON_VALUE()
връща единична текстова стойност от типnvarchar(4000)
Пример 1 – Извличане на скаларна стойност
Ето пример за демонстриране на разликата между тези функции, когато се опитвате да извлечете скаларна стойност.
SELECT JSON_VALUE('{"Name":"Homer"}', '$.Name') КАТО 'JSON_VALUE', JSON_QUERY('{"Name":"Homer"}', '$.Name') КАТО 'JSON_QUERY';
Резултат:
<пред>+--------------+--------------+| JSON_VALUE | JSON_QUERY ||--------------+--------------|| Омир | NULL |+--------------+--------------+
Така че и двете функции се опитват да извлекат една и съща стойност от JSON документа, но само една успява:JSON_VALUE()
. Това е така, защото стойността, която се опитват да извлекат, е скаларна стойност. По принцип, скаларна стойност е една единица данни. Може да е низ от текст или число. Но не може да бъде обект или масив.
Пример 2 – Извличане на масив
В този пример и двете функции се опитват да извлекат цял масив.
DECLARE @data NVARCHAR(4000)SET @data=N'{ "Sospect":{ "Име":"Хоумър Симпсън", "Хобита":["Хранене", "Спане", "Скачане на бейсбол"] } }' ИЗБЕРЕТЕ JSON_VALUE(@data,'$.Suspect.Hobbies') КАТО 'JSON_VALUE', JSON_QUERY(@data,'$.Suspect.Hobbies') КАТО 'JSON_QUERY';
Резултат:
+--------------+------------------------------ ---------+| JSON_VALUE | JSON_QUERY ||--------------+-------------------------------- --------|| NULL | ["Хранене", "Спи", "Скачане на база"] |+--------------+------------------- ---------------------+
В този случай само JSON_QUERY()
функцията е успешна.
Пример 3 – Извличане на елемент от масив
Този пример е подобен на предишния, с изключение на това, че вместо да се опитваме да извлечем целия масив, искаме само един елемент от масива.
DECLARE @data NVARCHAR(4000)SET @data=N'{ "Sospect":{ "Име":"Хоумър Симпсън", "Хобита":["Хранене", "Спане", "Скачане на бейсбол"] } }' ИЗБЕРЕТЕ JSON_VALUE(@data,'$.Suspect.Hobbies[2]') КАТО 'JSON_VALUE', JSON_QUERY(@data,'$.Suspect.Hobbies[2]') КАТО 'JSON_QUERY';
Резултат:
<пред>+--------------+--------------+| JSON_VALUE | JSON_QUERY ||--------------+--------------|| Бейс скокове | NULL |+--------------+--------------+
Така че този път JSON_VALUE()
е победител.
Пример 4 – Извличане на обект
Нека опитаме за цял обект.
DECLARE @data NVARCHAR(4000)SET @data=N'{ "Sospect":{ "Име":"Хоумър Симпсън", "Хобита":["Хранене", "Спане", "Скачане на бейсбол"] } }' ИЗБЕРЕТЕ JSON_VALUE(@data,'$.Suspect') КАТО 'JSON_VALUE', JSON_QUERY(@data,'$.Suspect') КАТО 'JSON_QUERY';
Резултат:
<пред>+--------------+--------------+| JSON_VALUE | JSON_QUERY ||--------------+--------------|| NULL | { "Име":"Хоумър Симпсън", "Хобита":["Хранене", "Спане", "Скачане на база"] } |+--------------+---- ----------+
И JSON_QUERY()
победи.
(Извинете за форматирането, ето как моят инструмент за команден ред MSSQL връща резултатите).
Пример 5 – Извличане на целия JSON документ
Нека опитаме за целия JSON документ.
DECLARE @data NVARCHAR(4000)SET @data=N'{ "Градове":[ { "Име":"Кабул", "Код на страната":"AFG", "Округ":"Кабол", "Население" :1780000 }, { "Име":"Кандахар", "Код на страната":"AFG", "Округ":"Кандахар", "Население":237500 } ]}'SELECT JSON_VALUE(@data, '$') AS ' JSON_VALUE', JSON_QUERY(@data, '$') КАТО 'JSON_QUERY';
Резултат:
<пред>+--------------+--------------+| JSON_VALUE | JSON_QUERY ||--------------+--------------|| NULL | { "Градове":[ { "Име":"Кабул", "Код на страната":"AFG", "Округ":"Кабол", "Население":1780000 }, { "Име":"Кандахар", "Код на страната" :"AFG", "District":"Qandahar", "Население":237500 } ]} |+--------------+------------ --+
Така че JSON_QUERY()
е единственият, който може да върне целия документ.
Пример 6 – Пропускане на пътя
Друга разлика между тези две функции е, че аргументът пътя не е задължителен при използване на JSON_QUERY()
. Ако пропуснете това, се връща целият JSON документ.
Не можете да пропуснете този аргумент, когато използвате JSON_VALUE()
, тъй като това е задължителен аргумент. Това вероятно се дължи на факта, че функцията може да върне само скаларна стойност. Ако първият аргумент се състои само от скаларна стойност, той няма да е валиден JSON.
Както и да е, ето пример за пропускане на аргумента за път от JSON_QUERY()
:
SELECT JSON_QUERY('{"Име":"Homer"}') КАТО 'Резултат';
Резултат:
+------------------+| Резултат ||------------------|| {"Име":"Омир"} |+------------------+
И ето какво се случва, ако опитаме този трик с JSON_VALUE()
:
SELECT JSON_VALUE('{"Име":"Homer"}') КАТО 'Резултат';
Резултат:
Съобщение 174, ниво 15, състояние 1, ред 1. Функцията json_value изисква 2 аргумента.
Пример 7 – Режим на пътя
В по-ранните примери, когато функция не може да се справи с предоставения път, тя връща NULL
. Това е така, защото всички тези примери бяха стартирани в слаб режим (режимът по подразбиране).
Ако ги стартираме в строг режим, вместо това щяхме да получим грешка. За да посочите изрично режима на пътя, просто го добавете преди знака за долар (и оставете интервал между тях).
Ето пример за това какво се случва, когато предоставите невалиден път, докато сте в строг режим:
SELECT JSON_VALUE('{"Име":"Homer"}', 'строго $.Name') КАТО 'JSON_VALUE', JSON_QUERY('{"Name":"Homer"}', 'строго $.Name' ) КАТО 'JSON_QUERY';
Резултат:
Съобщение 13624, ниво 16, състояние 2, ред 1 Обектът или масивът не могат да бъдат намерени в посочения JSON път.