Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Как да изберете вложен JSON в SQL Server с OPENJSON

Ако използвате OPENJSON() , но се опитвате да запомните как да изберете вътрешен фрагмент от JSON документа, прочетете нататък.

OPENJSON() синтаксисът ви позволява да конвертирате JSON документи в табличен изглед. Освен това ви позволява да изберете вложен JSON фрагмент от JSON документа.

Начинът да направите това е с пътеки .

Пътища

Пътят се състои от следното:

  • Знак за долар ($ ), който представлява контекстния елемент.
  • Набор от стъпки по пътя. Стъпките на пътя могат да съдържат следните елементи и оператори:
    • Ключови имена. Например, $.pets и $.pets.dogs . Ако името на ключа започва със знак за долар или съдържа специални знаци като интервали, то трябва да бъде заобиколено с кавички (например $."my pets" ).
    • Елементи на масива. Например, $.pets.dogs[1] . Индексите на масива са базирани на нула, така че този пример избира втория елемент в масива.
    • Операторът точка (. ) указва член на обект. Например в $.pets.dogs , кучета е член на домашни животни .

Основен пример

Ето един прост пример за демонстрация.

DECLARE @json NVARCHAR(4000) =N'{ "домашни любимци" :{ "котки" :[ { "id" :1, "name" :"Пухкав", "sex" :"Женски" } , { "id" :2, "name" :"Дълга опашка", "sex" :"Женски" }, { "id" :3, "name" :"Scratch", "sex" :"Мъж" } ] , "dogs" :[ { "id" :1, "name" :"Fetch", "sex" :"Male" }, { "id" :2, "name" :"Fluffy", "sex" :" Мъж" }, { "id" :3, "name" :"Wag", "sex" :"Female" } ] }}';ИЗБЕРЕТЕ *ОТ OPENJSON(@json, '$.pets.dogs')С ( [id] int, [name] varchar(60), [sex] varchar(6) ); 

Резултат:

+------+-------+-------+| ID | име | секс ||------+--------+--------|| 1 | Вземи | Мъжки || 2 | Пухкави | Мъжки || 3 | Размахване | Жена |+------+-------+-------+

В този случай вторият аргумент на OPENJSON() е '$.pets.dogs' , което означава, че избираме стойността на dogs ключ, който сам по себе си е дете на domets .

Знакът на долара ($ ) представлява контекстния елемент.

Имайте предвид, че в този пример използвам и WITH клауза за дефиниране на схемата. Ако не го включих, вместо това ще се използва схемата по подразбиране.

Ето как изглежда с помощта на схемата по подразбиране.

DECLARE @json NVARCHAR(4000) =N'{ "домашни любимци" :{ "котки" :[ { "id" :1, "name" :"Пухкав", "sex" :"Женски" } , { "id" :2, "name" :"Дълга опашка", "sex" :"Женски" }, { "id" :3, "name" :"Scratch", "sex" :"Мъж" } ] , "dogs" :[ { "id" :1, "name" :"Fetch", "sex" :"Male" }, { "id" :2, "name" :"Fluffy", "sex" :" Мъж" }, { "id" :3, "name" :"Wag", "sex" :"Female" } ] }}';SELECT *FROM OPENJSON(@json, '$.pets.dogs'); 

Резултат:

+-------+---------------------------------------------- -----------+-------+| ключ | стойност | тип ||-------+--------------------------------------- ---------+-------|| 0 | { "id" :1, "name" :"Извличане", "sex" :"Мъж" } | 5 || 1 | { "id" :2, "name" :"Пухкав", "sex" :"Мъжки" } | 5 || 2 | { "id" :3, "name" :"Wag", "sex" :"Female" } | 5 |+-------+------------------------------------------------ ----------+--------+

Така че все още избираме същия вложен JSON, просто използваме различна схема.

Схемата по подразбиране винаги връща три колони; ключ ,стойност , и тип .

Избор на елементи на масив

Както споменахме, можете да използвате нотацията в квадратни скоби, за да изберете конкретен елемент в масив.

Ето един пример.

DECLARE @json NVARCHAR(4000) =N'{ "домашни любимци" :{ "котки" :[ { "id" :1, "name" :"Пухкав", "sex" :"Женски" } , { "id" :2, "name" :"Дълга опашка", "sex" :"Женски" }, { "id" :3, "name" :"Scratch", "sex" :"Мъж" } ] , "dogs" :[ { "id" :1, "name" :"Fetch", "sex" :"Male" }, { "id" :2, "name" :"Fluffy", "sex" :" Мъж" }, { "id" :3, "name" :"Wag", "sex" :"Female" } ] }}';SELECT *FROM OPENJSON(@json, '$.pets.dogs[0]' )С ( [id] int, [name] varchar(60), [sex] varchar(6) ); 

Резултат:

+------+-------+-------+| ID | име | секс ||------+-------+-------|| 1 | Вземи | Мъжки |+------+-------+-------+

Виждайки, че индексите на масива са базирани на нула, посочвайки стойност от 0 връща първия елемент в масива.

Ето как изглежда този пример, когато се използва схемата по подразбиране (т.е. без WITH клауза).

DECLARE @json NVARCHAR(4000) =N'{ "домашни любимци" :{ "котки" :[ { "id" :1, "name" :"Пухкав", "sex" :"Женски" } , { "id" :2, "name" :"Дълга опашка", "sex" :"Женски" }, { "id" :3, "name" :"Scratch", "sex" :"Мъж" } ] , "dogs" :[ { "id" :1, "name" :"Fetch", "sex" :"Male" }, { "id" :2, "name" :"Fluffy", "sex" :" Мъж" }, { "id" :3, "name" :"Wag", "sex" :"Female" } ] }}';SELECT *FROM OPENJSON(@json, '$.pets.dogs[0]' ); 

Резултат:

<пред>+-------+--------+-------+| ключ | стойност | тип ||-------+--------+-------|| ID | 1 | 2 || име | Вземи | 1 || секс | Мъжки | 1 |+-------+--------+-------+

Режим на пътя

Когато използвате пътища, имате възможност да декларирате режима на пътя.

Режимът на пътя определя какво се случва, когато изразът за път съдържа грешка.

Режимът на пътя може да бъде или слаб или строго .

  • В слаб режим, функцията връща празни стойности, ако пътят не може да бъде намерен. Например, ако поискате стойността $.pets.cows , но JSON не съдържа този ключ, функцията връща null, но не предизвиква грешка.
  • В строго режим, функцията повдига грешка, ако пътят не може да бъде намерен.

Режимът на пътя по подразбиране е lax , така че ако не го декларирате, lax се използва.

Пример

Ето пример, за да демонстрирате как всеки режим на пътя обработва липсващи пътища.

Лекав режим

DECLARE @json NVARCHAR(4000) =N'{ "домашни любимци" :{ "котки" :[ { "id" :1, "name" :"Пухкав", "sex" :"Женски" } , { "id" :2, "name" :"Дълга опашка", "sex" :"Женски" }, { "id" :3, "name" :"Scratch", "sex" :"Мъж" } ] , "dogs" :[ { "id" :1, "name" :"Fetch", "sex" :"Male" }, { "id" :2, "name" :"Fluffy", "sex" :" Мъж" }, { "id" :3, "name" :"Wag", "sex" :"Female" } ] }}';SELECT *FROM OPENJSON(@json, 'lax $.pets.cows');  

Резултат:

(0 засегнати реда)

Така че слабият режим не доведе до грешки. Това просто доведе до нула редове, които бяха засегнати.

Ако посочихме нашата собствена схема и избрахме правилния подобект, но използвахме липсващ път, за да съпоставим с име на колона, той ще върне NULL в тази колона.

DECLARE @json NVARCHAR(4000) =N'{ "домашни любимци" :{ "котки" :[ { "id" :1, "name" :"Пухкав", "sex" :"Женски" } , { "id" :2, "name" :"Дълга опашка", "sex" :"Женски" }, { "id" :3, "name" :"Scratch", "sex" :"Мъж" } ] , "dogs" :[ { "id" :1, "name" :"Fetch", "sex" :"Male" }, { "id" :2, "name" :"Fluffy", "sex" :" Мъж" }, { "id" :3, "name" :"Wag", "sex" :"Female" } ] }}'ИЗБЕРЕТЕ *ОТ OPENJSON(@json, 'lax $.pets.dogs')С ( [id] int 'lax $.id', [name] varchar(60) 'lax $.name', [color] varchar(6) 'lax $.color' ); 

Резултат:

+------+--------+--------+| ID | име | цвят ||------+-------+--------|| 1 | Вземи | NULL || 2 | Пухкави | NULL || 3 | Размахване | NULL |+------+-------+--------+

Строк режим

Ето какво се случва, когато използваме строг режим.

DECLARE @json NVARCHAR(4000) =N'{ "домашни любимци" :{ "котки" :[ { "id" :1, "name" :"Пухкав", "sex" :"Женски" } , { "id" :2, "name" :"Дълга опашка", "sex" :"Женски" }, { "id" :3, "name" :"Scratch", "sex" :"Мъж" } ] , "dogs" :[ { "id" :1, "name" :"Fetch", "sex" :"Male" }, { "id" :2, "name" :"Fluffy", "sex" :" Мъж" }, { "id" :3, "name" :"Wag", "sex" :"Female" } ] }}';SELECT *FROM OPENJSON(@json, 'строг $.pets.cows');  

Резултат:

Съобщение 13608, ниво 16, състояние 3, ред 16 Свойството не може да бъде намерено на посочения JSON път.

Както се очакваше, това доведе до грешка.

Същата грешка възниква, когато изберем правилния JSON ключ, но съпоставим колона с несъществуващ ключ.

DECLARE @json NVARCHAR(4000) =N'{ "домашни любимци" :{ "котки" :[ { "id" :1, "name" :"Пухкав", "sex" :"Женски" } , { "id" :2, "name" :"Дълга опашка", "sex" :"Женски" }, { "id" :3, "name" :"Scratch", "sex" :"Мъж" } ] , "dogs" :[ { "id" :1, "name" :"Fetch", "sex" :"Male" }, { "id" :2, "name" :"Fluffy", "sex" :" Мъж" }, { "id" :3, "name" :"Wag", "sex" :"Female" } ] }}';ИЗБЕРЕТЕ *ОТ OPENJSON(@json, 'строг $.pets.dogs')С ( [id] int 'строг $.id', [name] varchar(60) 'строг $.name', [color] varchar(6) 'строг $.color' ); 

Резултат:

Съобщение 13608, ниво 16, състояние 6, ред 16 Свойството не може да бъде намерено на посочения JSON път.

Дублиращи се пътища

Ако вашият JSON документ съдържа дублиращи се пътища на едно и също ниво на влагане, OPENJSON() може да ги върне всичките.

Това е в контраст с JSON_VALUE() и JSON_QUERY() , като и двете връщат само първата стойност, която съответства на пътя.

Ето пример за използване на OPENJSON() за връщане на дублиращи се пътища.

DECLARE @json NVARCHAR(4000) =N'{ "dog":{ "names":{ "name":"Fetch", "name":"Good Dog" } } }';SELECT * ОТ OPENJSON(@json, '$.dog.names'); 

Резултат:

<пред>+-------+---------+-------+| ключ | стойност | тип ||-------+---------+-------|| име | Вземи | 1 || име | Добро куче | 1 |+-------+---------+-------+

Вложени подобекти

Когато дефинирате своя собствена схема, можете да използвате AS JSON опция за връщане на цял подобект като свой собствен JSON документ.

DECLARE @json NVARCHAR(4000) =N'{ "домашни любимци" :{ "котки" :[ { "id" :1, "name" :"Пухкав", "sex" :"Женски" } , { "id" :2, "name" :"Дълга опашка", "sex" :"Женски" }, { "id" :3, "name" :"Scratch", "sex" :"Мъж" } ] , "dogs" :[ { "id" :1, "name" :"Fetch", "sex" :"Male" }, { "id" :2, "name" :"Fluffy", "sex" :" Мъж" }, { "id" :3, "name" :"Wag", "sex" :"Female" } ] }}';SELECT *FROM OPENJSON(@json, '$.pets')WITH ( [dogs ] nvarchar(max) '$.dogs' КАТО JSON ); 

Резултат:

+--------+| кучета ||--------|| [ { "id" :1, "name" :"Извличане", "sex" :"Мъж" }, { "id" :2, "name" :"Fluffy", "sex" :"Мъж" }, { "id" :3, "name" :"Wag", "sex" :"Female" } ] |+--------+

Ако не бяхме използвали AS JSON опция, щяхме да получим грешка или NULL, в зависимост от това дали сме посочили lax или строго режим.

Ето го във всеки режим, когато се пропуска AS JSON опция.

Лекав режим

DECLARE @json NVARCHAR(4000) =N'{ "домашни любимци" :{ "котки" :[ { "id" :1, "name" :"Пухкав", "sex" :"Женски" } , { "id" :2, "name" :"Дълга опашка", "sex" :"Женски" }, { "id" :3, "name" :"Scratch", "sex" :"Мъж" } ] , "dogs" :[ { "id" :1, "name" :"Fetch", "sex" :"Male" }, { "id" :2, "name" :"Fluffy", "sex" :" Мъж" }, { "id" :3, "name" :"Wag", "sex" :"Female" } ] }}';SELECT *FROM OPENJSON(@json, '$.pets')WITH ( [dogs ] nvarchar(max) 'lax $.dogs' ); 

Резултат:

+--------+| кучета ||--------|| NULL |+--------+

Строк режим

DECLARE @json NVARCHAR(4000) =N'{ "домашни любимци" :{ "котки" :[ { "id" :1, "name" :"Пухкав", "sex" :"Женски" } , { "id" :2, "name" :"Дълга опашка", "sex" :"Женски" }, { "id" :3, "name" :"Scratch", "sex" :"Мъж" } ] , "dogs" :[ { "id" :1, "name" :"Fetch", "sex" :"Male" }, { "id" :2, "name" :"Fluffy", "sex" :" Мъж" }, { "id" :3, "name" :"Wag", "sex" :"Female" } ] }}';SELECT *FROM OPENJSON(@json, '$.pets')WITH ( [dogs ] nvarchar(max) 'строг $.dogs' ); 

Резултат:

Съобщение 13624, ниво 16, състояние 1, ред 16 Обектът или масивът не могат да бъдат намерени в посочения JSON път.

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Скрипт за запазване на varbinary данни на диск

  2. Как да направите UPDATE Pass-Through заявка в SQL Server

  3. Връщане на процент от набор от резултати в SQL Server

  4. алтернативи на REPLACE на текстов или ntext тип данни

  5. Как да прехвърлите DateTime към Time