Två av de många T-SQL-funktionerna som är tillgängliga i SQL Server är JSON_QUERY()
och JSON_VALUE()
. Dessa funktioner kan användas för att extrahera data från JSON-dokument.
Deras allmänna syntax är liknande, och vid första anblicken kanske du tror att de gör exakt samma sak, men det gör de inte. Det finns definitivt plats för båda funktionerna när du arbetar med JSON och SQL Server.
Den här artikeln tittar på skillnaden mellan JSON_QUERY()
och JSON_VALUE()
.
Skillnaden
Dessa två funktioner har lite olika definitioner, en något annorlunda syntax och deras returvärden är något olika.
Definitioner
Så här definieras de två funktionerna:
JSON_QUERY()
- Extraherar ett objekt eller en array från en JSON-sträng.
JSON_VALUE()
- Extraherar ett skalärt värde från en JSON-sträng.
Så skillnaden mellan dessa två funktioner är vad de extraherar. Den ena extraherar ett objekt eller en array, den andra extraherar ett skalärt värde.
Syntaxskillnader
En annan skillnad är i syntaxen:
JSON_QUERY ( expression [ , path ] ) JSON_VALUE ( expression , path )
Titta på JSON_QUERY()
syntax. De där hakparenteserna runt path
argument betyder att det är ett valfritt argument. Det beror på att den här funktionen kan returnera ett helt JSON-dokument om det behövs.
Men sökvägsargumentet är ett obligatoriskt argument när du använder JSON_VALUE()
fungera. Så du måste ange båda argumenten när du använder den här funktionen.
Returvärden
Och ytterligare en skillnad är deras avkastningsvärden.
JSON_QUERY()
returnerar ett JSON-fragment av typennvarchar(max)
JSON_VALUE()
returnerar ett enstaka textvärde av typennvarchar(4000)
Exempel 1 – Extrahera ett skalärt värde
Här är ett exempel för att visa skillnaden mellan dessa funktioner när du försöker extrahera ett skalärt värde.
SELECT JSON_VALUE('{"Name": "Homer"}', '$.Name') AS 'JSON_VALUE', JSON_QUERY('{"Name": "Homer"}', '$.Name') AS 'JSON_QUERY';
Resultat:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | Homer | NULL | +--------------+--------------+
Så båda funktionerna försöker extrahera samma värde från JSON-dokumentet, men bara en lyckas:JSON_VALUE()
. Detta beror på att värdet de försöker extrahera är ett skalärt värde. I grund och botten ett skalärt värde är en dataenhet. Det kan vara en textsträng eller ett nummer. Men det kan inte vara ett objekt eller en array.
Exempel 2 – Extrahera en array
I det här exemplet försöker båda funktionerna extrahera en hel array.
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Suspect": { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } }' SELECT JSON_VALUE(@data,'$.Suspect.Hobbies') AS 'JSON_VALUE', JSON_QUERY(@data,'$.Suspect.Hobbies') AS 'JSON_QUERY';
Resultat:
+--------------+----------------------------------------+ | JSON_VALUE | JSON_QUERY | |--------------+----------------------------------------| | NULL | ["Eating", "Sleeping", "Base Jumping"] | +--------------+----------------------------------------+
I det här fallet, endast JSON_QUERY()
funktionen lyckas.
Exempel 3 – Extrahera ett matrisobjekt
Det här exemplet liknar det föregående, förutom att istället för att försöka extrahera hela arrayen vill vi bara ha ett enda objekt från arrayen.
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Suspect": { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } }' SELECT JSON_VALUE(@data,'$.Suspect.Hobbies[2]') AS 'JSON_VALUE', JSON_QUERY(@data,'$.Suspect.Hobbies[2]') AS 'JSON_QUERY';
Resultat:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | Base Jumping | NULL | +--------------+--------------+
Så den här gången JSON_VALUE()
är vinnaren.
Exempel 4 – Extrahera ett objekt
Låt oss försöka hitta ett helt objekt.
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Suspect": { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } }' SELECT JSON_VALUE(@data,'$.Suspect') AS 'JSON_VALUE', JSON_QUERY(@data,'$.Suspect') AS 'JSON_QUERY';
Resultat:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | NULL | { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } | +--------------+--------------+
Och JSON_QUERY()
vinner.
(Ursäkta formateringen, det är så här mitt MSSQL-kommandoradsverktyg returnerar resultaten).
Exempel 5 – Extrahera hela JSON-dokumentet
Låt oss försöka hitta hela JSON-dokumentet.
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_VALUE(@data, '$') AS 'JSON_VALUE', JSON_QUERY(@data, '$') AS 'JSON_QUERY';
Resultat:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | NULL | { "Cities": [ { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 }, { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } ] } | +--------------+--------------+
Alltså JSON_QUERY()
är den enda som kan returnera hela dokumentet.
Exempel 6 – Utelämna sökvägen
En annan skillnad mellan dessa två funktioner är att sökvägsargumentet är valfritt när du använder JSON_QUERY()
. Om du utelämnar detta returneras hela JSON-dokumentet.
Du kan inte utelämna detta argument när du använder JSON_VALUE()
, eftersom det är ett obligatoriskt argument. Detta beror förmodligen på att funktionen bara kan returnera ett skalärt värde. Om det första argumentet bara bestod av ett skalärt värde, skulle det inte vara giltigt JSON.
Hur som helst, här är ett exempel på att utelämna sökvägsargumentet från JSON_QUERY()
:
SELECT JSON_QUERY('{"Name": "Homer"}') AS 'Result';
Resultat:
+-------------------+ | Result | |-------------------| | {"Name": "Homer"} | +-------------------+
Och här är vad som händer om vi provar det tricket med JSON_VALUE()
:
SELECT JSON_VALUE('{"Name": "Homer"}') AS 'Result';
Resultat:
Msg 174, Level 15, State 1, Line 1 The json_value function requires 2 argument(s).
Exempel 7 – Path Mode
I de tidigare exemplen, när en funktion inte kunde hantera den angivna sökvägen, returnerade den NULL
. Detta beror på att alla dessa exempel kördes i slappt läge (standardläget).
Om vi hade kört dem i strikt läge, skulle vi ha fått ett felmeddelande istället. För att uttryckligen ange sökvägsläget, lägg helt enkelt till det före dollartecknet (och lämna ett mellanslag mellan dem).
Här är ett exempel på vad som händer när du anger en ogiltig sökväg i strikt läge:
SELECT JSON_VALUE('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_VALUE', JSON_QUERY('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_QUERY';
Resultat:
Msg 13624, Level 16, State 2, Line 1 Object or array cannot be found in the specified JSON path.