Pokud používáte OPENJSON()
, ale snažíte se zapamatovat si, jak vybrat vnitřní fragment z dokumentu JSON, čtěte dále.
OPENJSON()
syntaxe umožňuje převádět dokumenty JSON do tabulkového zobrazení. Umožňuje vám také vybrat vnořený fragment JSON z dokumentu JSON.
Způsob, jak toho dosáhnout, je pomocí cest .
Cesty
Cesta se skládá z následujícího:
- Znak dolaru (
$
), která představuje kontextovou položku. - Sada kroků cesty. Kroky cesty mohou obsahovat následující prvky a operátory:
- Jména klíčů. Například
$.pets
a$.pets.dogs
. Pokud název klíče začíná znakem dolaru nebo obsahuje speciální znaky, jako jsou mezery, musí být obklopen uvozovkami (například$."my pets"
). - Prvky pole. Například
$.pets.dogs[1]
. Indexy pole jsou založeny na nule, takže tento příklad vybere druhý prvek v poli. - Tečkový operátor (
.
) označuje člena objektu. Například v$.pets.dogs
,dogs
je členempets
.
- Jména klíčů. Například
Základní příklad
Zde je jednoduchý příklad k demonstraci.
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets.dogs')
WITH (
[id] int,
[name] varchar(60),
[sex] varchar(6)
);
Výsledek:
+------+--------+--------+ | id | name | sex | |------+--------+--------| | 1 | Fetch | Male | | 2 | Fluffy | Male | | 3 | Wag | Female | +------+--------+--------+
V tomto případě druhý argument pro OPENJSON()
je '$.pets.dogs'
, což znamená, že vybíráme hodnotu dogs
klíč, který je sám o sobě potomkem pets
.
Znak dolaru ($
) představuje kontextovou položku.
Všimněte si, že v tomto příkladu také používám WITH
klauzule k definování schématu. Pokud bych to nezahrnul, místo toho by se použilo výchozí schéma.
Zde je návod, jak to vypadá s použitím výchozího schématu.
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets.dogs');
Výsledek:
+-------+-------------------------------------------------+--------+ | key | value | type | |-------+-------------------------------------------------+--------| | 0 | { "id" : 1, "name" : "Fetch", "sex" : "Male" } | 5 | | 1 | { "id" : 2, "name" : "Fluffy", "sex" : "Male" } | 5 | | 2 | { "id" : 3, "name" : "Wag", "sex" : "Female" } | 5 | +-------+-------------------------------------------------+--------+
Stále tedy vybíráme stejný vnořený JSON, jen používáme jiné schéma.
Výchozí schéma vždy vrací tři sloupce; klíč , hodnota a zadejte .
Výběr prvků pole
Jak již bylo zmíněno, k výběru konkrétního prvku v poli můžete použít notaci hranatých závorek.
Zde je příklad.
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets.dogs[0]')
WITH (
[id] int,
[name] varchar(60),
[sex] varchar(6)
);
Výsledek:
+------+--------+-------+ | id | name | sex | |------+--------+-------| | 1 | Fetch | Male | +------+--------+-------+
Indexy pole jsou založeny na nule a uvádějí hodnotu 0
vrátí první prvek v poli.
Takto vypadá tento příklad při použití výchozího schématu (tj. bez WITH
doložka).
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets.dogs[0]');
Výsledek:
+-------+---------+--------+ | key | value | type | |-------+---------+--------| | id | 1 | 2 | | name | Fetch | 1 | | sex | Male | 1 | +-------+---------+--------+
Režim cesty
Při použití cest máte možnost deklarovat režim cesty.
Režim cesty určuje, co se stane, když výraz cesty obsahuje chybu.
Režim cesty může být buď lax
nebo strict
.
- V
lax
režimu, funkce vrátí prázdné hodnoty, pokud cestu nelze najít. Pokud například požadujete hodnotu$.pets.cows
, ale JSON tento klíč neobsahuje, funkce vrátí hodnotu null, ale nevyvolá chybu. - V
strict
režimu, funkce vyvolá chybu, pokud cestu nelze najít.
Výchozí režim cesty je lax
, takže pokud to nedeklarujete, lax
se používá.
Příklad
Zde je příklad demonstrující, jak každý režim cesty zpracovává chybějící cesty.
Laxní režim
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, 'lax $.pets.cows');
Výsledek:
(0 rows affected)
Laxní režim tedy nevyvolal žádné chyby. Jednoduše to vedlo k ovlivnění nula řádků.
Pokud bychom zadali vlastní schéma a vybrali správný dílčí objekt, ale použili jsme chybějící cestu k mapování na název sloupce, vrátilo by to NULL
v tomto sloupci.
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}'
SELECT *
FROM OPENJSON(@json, 'lax $.pets.dogs')
WITH (
[id] int 'lax $.id',
[name] varchar(60) 'lax $.name',
[color] varchar(6) 'lax $.color'
);
Výsledek:
+------+--------+---------+ | id | name | color | |------+--------+---------| | 1 | Fetch | NULL | | 2 | Fluffy | NULL | | 3 | Wag | NULL | +------+--------+---------+
Přísný režim
Zde je to, co se stane, když použijeme přísný režim.
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, 'strict $.pets.cows');
Výsledek:
Msg 13608, Level 16, State 3, Line 16 Property cannot be found on the specified JSON path.
Podle očekávání došlo k chybě.
Ke stejné chybě dojde, když vybereme správný klíč JSON, ale namapujeme sloupec na neexistující klíč.
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, 'strict $.pets.dogs')
WITH (
[id] int 'strict $.id',
[name] varchar(60) 'strict $.name',
[color] varchar(6) 'strict $.color'
);
Výsledek:
Msg 13608, Level 16, State 6, Line 16 Property cannot be found on the specified JSON path.
Duplicitní cesty
Pokud váš dokument JSON obsahuje duplicitní cesty na stejné úrovni vnoření, OPENJSON()
může je všechny vrátit.
To je v kontrastu s JSON_VALUE()
a JSON_QUERY()
, obě vracejí pouze první hodnotu, která odpovídá cestě.
Zde je příklad použití OPENJSON()
vrátit duplicitní cesty.
DECLARE @json NVARCHAR(4000) = N'{
"dog": {
"names": {
"name": "Fetch",
"name": "Good Dog"
}
}
}';
SELECT * FROM OPENJSON(@json, '$.dog.names');
Výsledek:
+-------+----------+--------+ | key | value | type | |-------+----------+--------| | name | Fetch | 1 | | name | Good Dog | 1 | +-------+----------+--------+
Vnořené dílčí objekty
Při definování vlastního schématu můžete použít AS JSON
možnost vrátit celý dílčí objekt jako svůj vlastní dokument JSON.
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets')
WITH (
[dogs] nvarchar(max) '$.dogs' AS JSON
);
Výsledek:
+--------+ | dogs | |--------| | [ { "id" : 1, "name" : "Fetch", "sex" : "Male" }, { "id" : 2, "name" : "Fluffy", "sex" : "Male" }, { "id" : 3, "name" : "Wag", "sex" : "Female" } ] | +--------+
Pokud bychom nepoužili AS JSON
možnost, dostali bychom chybu nebo NULL, v závislosti na tom, zda jsme zadali lax
nebo strict
režimu.
Zde je v každém režimu při vynechání AS JSON
možnost.
Laxní režim
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets')
WITH (
[dogs] nvarchar(max) 'lax $.dogs'
);
Výsledek:
+--------+ | dogs | |--------| | NULL | +--------+
Přísný režim
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets')
WITH (
[dogs] nvarchar(max) 'strict $.dogs'
);
Výsledek:
Msg 13624, Level 16, State 1, Line 16 Object or array cannot be found in the specified JSON path.