Om du använder OPENJSON()
, men du försöker komma ihåg hur du väljer ett inre fragment från JSON-dokumentet, läs vidare.
OPENJSON()
syntax låter dig konvertera JSON-dokument till en tabellvy. Det låter dig också välja ett kapslat JSON-fragment från JSON-dokumentet.
Sättet att göra detta är med sökvägar .
Vägar
En sökväg består av följande:
- Ett dollartecken (
$
), som representerar kontextobjektet. - En uppsättning vägsteg. Sökvägssteg kan innehålla följande element och operatorer:
- Nyckelnamn. Till exempel
$.pets
och$.pets.dogs
. Om nyckelnamnet börjar med ett dollartecken eller innehåller specialtecken som mellanslag måste det omges av citattecken (till exempel$."my pets"
). - Arrayelement. Till exempel,
$.pets.dogs[1]
. Arrayindex är nollbaserade, så det här exemplet väljer det andra elementet i arrayen. - Prickoperatorn (
.
) indikerar en medlem av ett objekt. Till exempel i$.pets.dogs
,dogs
är medlem ipets
.
- Nyckelnamn. Till exempel
Grundläggande exempel
Här är ett enkelt exempel att visa.
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)
);
Resultat:
+------+--------+--------+ | id | name | sex | |------+--------+--------| | 1 | Fetch | Male | | 2 | Fluffy | Male | | 3 | Wag | Female | +------+--------+--------+
I det här fallet, det andra argumentet till OPENJSON()
är '$.pets.dogs'
, vilket betyder att vi väljer värdet för dogs
nyckel, som i sig är ett barn till pets
.
Dollartecknet ($
) representerar kontextobjektet.
Observera att i det här exemplet använder jag också WITH
klausul för att definiera schemat. Om jag inte inkluderade det skulle standardschemat användas istället.
Så här ser det ut med standardschemat.
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');
Resultat:
+-------+-------------------------------------------------+--------+ | 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 | +-------+-------------------------------------------------+--------+
Så vi väljer fortfarande samma kapslade JSON, det är bara det att vi använder ett annat schema.
Standardschemat returnerar alltid tre kolumner; nyckel , värde och skriv .
Välja matriselement
Som nämnts kan du använda notationen med hakparenteser för att välja ett specifikt element i en array.
Här är ett exempel.
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)
);
Resultat:
+------+--------+-------+ | id | name | sex | |------+--------+-------| | 1 | Fetch | Male | +------+--------+-------+
Eftersom arrayindex är nollbaserade, anger värdet 0
returnerar det första elementet i arrayen.
Så här ser det här exemplet ut när du använder standardschemat (dvs utan WITH
klausul).
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]');
Resultat:
+-------+---------+--------+ | key | value | type | |-------+---------+--------| | id | 1 | 2 | | name | Fetch | 1 | | sex | Male | 1 | +-------+---------+--------+
Sökväg
När du använder sökvägar har du möjlighet att deklarera sökvägsläget.
Sökvägsläge avgör vad som händer när ett sökvägsuttryck innehåller ett fel.
Sökvägsläget kan vara antingen lax
eller strict
.
- I
lax
läge returnerar funktionen tomma värden om sökvägen inte kan hittas. Till exempel, om du begär värdet$.pets.cows
, men JSON innehåller inte den nyckeln, returnerar funktionen null, men ger inget fel. - I
strict
läge ger funktionen ett felmeddelande om sökvägen inte kan hittas.
Standardsökvägsläget är lax
, så om du inte deklarerar det, lax
är använd.
Exempel
Här är ett exempel för att visa hur varje sökvägsläge hanterar saknade sökvägar.
Laxläge
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');
Resultat:
(0 rows affected)
Så slappt läge gav inga fel. Det resulterade helt enkelt i att noll rader påverkades.
Om vi angav vårt eget schema och vi valde rätt underobjekt, men vi använde en saknad sökväg för att mappa till ett kolumnnamn, skulle det returnera NULL
i den kolumnen.
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'
);
Resultat:
+------+--------+---------+ | id | name | color | |------+--------+---------| | 1 | Fetch | NULL | | 2 | Fluffy | NULL | | 3 | Wag | NULL | +------+--------+---------+
Strikt läge
Det här är vad som händer när vi använder strikt läge.
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');
Resultat:
Msg 13608, Level 16, State 3, Line 16 Property cannot be found on the specified JSON path.
Som väntat resulterade det i ett fel.
Samma fel uppstår när vi väljer rätt JSON-nyckel, men mappar en kolumn till en icke-existerande nyckel.
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'
);
Resultat:
Msg 13608, Level 16, State 6, Line 16 Property cannot be found on the specified JSON path.
Duplicera sökvägar
Om ditt JSON-dokument innehåller dubbletter av sökvägar på samma kapslingsnivå, OPENJSON()
kan returnera dem alla.
Detta är i motsats till JSON_VALUE()
och JSON_QUERY()
, som båda endast returnerar det första värdet som matchar sökvägen.
Här är ett exempel på hur du använder OPENJSON()
för att returnera dubbletter av sökvägar.
DECLARE @json NVARCHAR(4000) = N'{
"dog": {
"names": {
"name": "Fetch",
"name": "Good Dog"
}
}
}';
SELECT * FROM OPENJSON(@json, '$.dog.names');
Resultat:
+-------+----------+--------+ | key | value | type | |-------+----------+--------| | name | Fetch | 1 | | name | Good Dog | 1 | +-------+----------+--------+
Inkapslade underobjekt
När du definierar ditt eget schema kan du använda AS JSON
möjlighet att returnera ett helt underobjekt som sitt eget JSON-dokument.
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
);
Resultat:
+--------+ | dogs | |--------| | [ { "id" : 1, "name" : "Fetch", "sex" : "Male" }, { "id" : 2, "name" : "Fluffy", "sex" : "Male" }, { "id" : 3, "name" : "Wag", "sex" : "Female" } ] | +--------+
Om vi inte hade använt AS JSON
alternativet skulle vi ha fått ett felmeddelande eller NULL, beroende på om vi hade angett lax
eller strict
läge.
Här är det i varje läge när du utelämnar AS JSON
alternativ.
Laxläge
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'
);
Resultat:
+--------+ | dogs | |--------| | NULL | +--------+
Strikt läge
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'
);
Resultat:
Msg 13624, Level 16, State 1, Line 16 Object or array cannot be found in the specified JSON path.