När du använder JSON med SQL Server kan du använda JSON_QUERY()
funktion för att extrahera ett objekt eller en array från en JSON-sträng.
För att använda den här funktionen anger du JSON-uttrycket som ett argument. Du kan också tillhandahålla ett andra (valfritt) argument för att specificera objektet eller arrayen som ska extraheras.
Syntax
Syntaxen ser ut så här:
JSON_QUERY ( expression [ , path ] )
Där expression
är JSON-stränguttrycket och path
är objektet eller matrisen som du vill extrahera från uttrycket. path
argument är valfritt (om du inte tillhandahåller det returneras hela JSON-dokumentet).
Sökvägsargumentet (om det finns) kan inkludera ett valfritt sökvägsläge komponent. Detta valfria sökvägsläge kan vara ett värde av antingen lax
eller strict
. Detta värde avgör vad som händer om den angivna sökvägen är ogiltig. Banläget (om det finns) kommer före dollartecknet.
Exempel 1 – Grundläggande användning
Här är ett exempel för att visa grundläggande användning av JSON_QUERY()
funktion.
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Cities": [ { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 }, { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } ] }' SELECT JSON_QUERY(@data, '$.Cities[0]') AS 'Result';
Resultat:
+----------+ | Result | |----------| | { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 } | +----------+
I det här exemplet deklarerar och ställer jag först en variabel som heter @data
. Jag tilldelar sedan en array till denna variabel. När jag har gjort detta kör jag en fråga mot den arrayen.
I det här fallet använder jag Cities[0]
för att referera till det första objektet i arrayen (JSON-arrayer använder nollbaserad numrering).
Jag kunde komma åt det andra objektet genom att använda Cities[1]
. Så här:
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Cities": [ { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 }, { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } ] }' SELECT JSON_QUERY(@data, '$.Cities[1]') AS 'Result';
Resultat:
+----------+ | Result | |----------| | { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } | +----------+
Exempel 2 – Returnera hela JSON-uttrycket
Det andra argumentet är valfritt, så om du utelämnar det returneras hela JSON-dokumentet. Här är vad som händer när vi gör det med samma data från de tidigare exemplen:
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Cities": [ { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 }, { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } ] }' SELECT JSON_QUERY(@data) AS 'Result';
Resultat:
+----------+ | Result | |----------| | { "Cities": [ { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 }, { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } ] } | +----------+
Exempel 3 – Ett databasexempel
Om vi skulle lägga in data från föregående exempel i en databas skulle vi kunna skriva om frågan enligt följande:
SELECT JSON_QUERY(Document,'$.Cities[0]') AS 'City 1' FROM Json_Documents
Resultat:
+----------+ | City 1 | |----------| | { "ID": 1, "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 } | +----------+
Detta förutsätter att JSON-dokumentet lagras i en kolumn som heter Document
, som finns i en tabell som heter Json_Documents
.
Exempel 4 – Skalära värden
JSON_QUERY()
Funktionen är inte utformad för att returnera skalära värden. Om du vill returnera ett skalärt värde, använd JSON_VALUE()
funktion istället.
Det finns dock inget som hindrar dig från att kombinera båda funktionerna i en fråga för att returnera data på olika nivåer av granularitet.
Här är ett exempel:
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Suspect": { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } }' SELECT JSON_VALUE(@data,'$.Suspect.Name') AS 'Name', JSON_QUERY(@data,'$.Suspect.Hobbies') AS 'Hobbies', JSON_VALUE(@data,'$.Suspect.Hobbies[2]') AS 'Last Hobby';
Resultat:
+---------------+----------------------------------------+--------------+ | Name | Hobbies | Last Hobby | |---------------+----------------------------------------+--------------| | Homer Simpson | ["Eating", "Sleeping", "Base Jumping"] | Base Jumping | +---------------+----------------------------------------+--------------+
I det här exemplet använde jag JSON_VALUE()
för att extrahera olika skalära värden, men jag använde också JSON_QUERY()
för att returnera en hel array (som JSON_VALUE()
kan inte göra).
Exempel 5 – Path Mode
Som nämnts har du också möjlighet att ange sökvägsläge. Detta kan antingen vara lax
eller strict
.
Värdet för sökvägsläget avgör vad som händer när sökvägsuttrycket innehåller ett fel. Närmare bestämt:
- I slappa läget returnerar funktionen tomma värden om sökvägsuttrycket innehåller ett fel. Om du till exempel begär värdet $.name , och JSON-texten innehåller inget namn nyckel returnerar funktionen null, men ger inget fel.
-
I strikt läget ger funktionen ett fel om sökvägsuttrycket innehåller ett fel.
Standardvärdet är lax
.
Här är ett exempel för att visa skillnaden mellan dessa två lägen.
Fel i slappt läge
Här är vad som händer när sökvägsuttrycket innehåller ett fel i slappt läge.
SELECT JSON_QUERY('{"Name": "Bruce"}', 'lax $.Name') AS 'Result';
Resultat:
+----------+ | Result | |----------| | NULL | +----------+
I det här exemplet försöker vi returnera ett skalärt värde, men JSON_QUERY()
gör inte skalära värden. Som nämnts returnerar den bara objekt och arrayer. I det här fallet får vi ett nollvärde (eftersom vi använder slappt läge).
Fel i strikt läge
Det här är vad som händer när vi kör samma kod i strikt läge.
SELECT JSON_QUERY('{"Name": "Bruce"}', 'strict $.Name') AS 'Result';
Resultat:
Msg 13624, Level 16, State 2, Line 1 Object or array cannot be found in the specified JSON path.
Som väntat resulterar strikt läge i ett felmeddelande som förklarar felet.