Hvis du bruger OPENJSON()
, men du prøver at huske, hvordan du vælger et indre fragment fra JSON-dokumentet, læs videre.
OPENJSON()
syntaks giver dig mulighed for at konvertere JSON-dokumenter til en tabelvisning. Det giver dig også mulighed for at vælge et indlejret JSON-fragment fra JSON-dokumentet.
Måden at gøre dette på er med stier .
Stier
En sti består af følgende:
- Et dollartegn (
$
), som repræsenterer kontekstelementet. - Et sæt stitrin. Stitrin kan indeholde følgende elementer og operatorer:
- Nøglenavne. For eksempel
$.pets
og$.pets.dogs
. Hvis nøglenavnet starter med et dollartegn eller indeholder specialtegn såsom mellemrum, skal det være omgivet af anførselstegn (for eksempel$."my pets"
). - Array-elementer. For eksempel
$.pets.dogs[1]
. Array-indekser er nul-baserede, så dette eksempel vælger det andet element i arrayet. - Prikoperatoren (
.
) angiver et medlem af et objekt. For eksempel i$.pets.dogs
,dogs
er medlem afpets
.
- Nøglenavne. For eksempel
Grundlæggende eksempel
Her er et simpelt eksempel at demonstrere.
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 dette tilfælde er det andet argument til OPENJSON()
er '$.pets.dogs'
, hvilket betyder, at vi vælger værdien af dogs
nøgle, som selv er et barn af pets
.
Dollartegnet ($
) repræsenterer kontekstelementet.
Bemærk, at i dette eksempel bruger jeg også WITH
klausul for at definere skemaet. Hvis jeg ikke inkluderede det, ville standardskemaet blive brugt i stedet.
Sådan ser det ud med standardskemaet.
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ælger stadig den samme indlejrede JSON, det er bare, at vi bruger et andet skema.
Standardskemaet returnerer altid tre kolonner; tast , værdi , og skriv .
Valg af matrixelementer
Som nævnt kan du bruge notationen med firkantede parenteser til at vælge et specifikt element i en matrix.
Her er et eksempel.
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 | +------+--------+-------+
Da array-indekser er nul-baserede, angiver værdien 0
returnerer det første element i arrayet.
Sådan ser dette eksempel ud, når du bruger standardskemaet (dvs. uden 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 | +-------+---------+--------+
Stitilstand
Når du bruger stier, har du mulighed for at erklære stitilstanden.
Stitilstand bestemmer, hvad der sker, når et stiudtryk indeholder en fejl.
Stitilstand kan enten være lax
eller strict
.
- I
lax
tilstand, returnerer funktionen tomme værdier, hvis stien ikke kan findes. For eksempel, hvis du anmoder om værdien$.pets.cows
, men JSON'en indeholder ikke den nøgle, returnerer funktionen null, men frembringer ikke en fejl. - I
strict
tilstand, rejser funktionen en fejl, hvis stien ikke kan findes.
Standardstitilstanden er lax
, så hvis du ikke erklærer det, lax
anvendes.
Eksempel
Her er et eksempel for at demonstrere, hvordan hver stitilstand håndterer manglende stier.
Laks tilstand
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å slap tilstand gav ingen fejl. Det resulterede simpelthen i, at nul rækker blev påvirket.
Hvis vi specificerede vores eget skema, og vi valgte det korrekte underobjekt, men vi brugte en manglende sti til at tilknytte et kolonnenavn, ville det returnere NULL
i den kolonne.
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 tilstand
Her er, hvad der sker, når vi bruger streng tilstand.
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 forventet resulterede det i en fejl.
Den samme fejl opstår, når vi vælger den korrekte JSON-nøgle, men knytter en kolonne til en ikke-eksisterende nøgle.
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.
Dublerede stier
Hvis dit JSON-dokument indeholder duplikerede stier på samme indlejringsniveau, OPENJSON()
kan returnere dem alle.
Dette er i modsætning til JSON_VALUE()
og JSON_QUERY()
, som begge kun returnerer den første værdi, der matcher stien.
Her er et eksempel på brug af OPENJSON()
for at returnere duplikerede stier.
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 | +-------+----------+--------+
Indlejrede underobjekter
Når du definerer dit eget skema, kan du bruge AS JSON
mulighed for at returnere et helt underobjekt som sit 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" } ] | +--------+
Hvis vi ikke havde brugt AS JSON
mulighed, ville vi have modtaget en fejl eller NULL, afhængigt af om vi havde angivet lax
eller strict
tilstand.
Her er det i hver tilstand, når du udelader AS JSON
mulighed.
Laks tilstand
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 tilstand
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.