sql >> Database >  >> RDS >> Sqlserver

JSON_QUERY() versus JSON_VALUE() in SQL Server:wat is het verschil?

Twee van de vele T-SQL-functies die beschikbaar zijn in SQL Server zijn JSON_QUERY() en JSON_VALUE() . Deze functies kunnen worden gebruikt om gegevens uit JSON-documenten te extraheren.

Hun algemene syntaxis is vergelijkbaar, en op het eerste gezicht zou je kunnen denken dat ze precies hetzelfde doen, maar dat doen ze niet. Er is zeker plaats voor beide functies bij het werken met JSON en SQL Server.

Dit artikel gaat in op het verschil tussen JSON_QUERY() en JSON_VALUE() .

Het verschil

Deze twee functies hebben iets verschillende definities, een iets andere syntaxis en hun retourwaarden zijn iets anders.

Definities

Zo worden de twee functies gedefinieerd:

JSON_QUERY()
Haalt een object of een array uit een JSON-tekenreeks.
JSON_VALUE()
Haalt een scalaire waarde uit een JSON-tekenreeks.

Dus het verschil tussen deze twee functies is wat ze extraheren. De ene extraheert een object of een array, de andere extraheert een scalaire waarde.

Syntaxisverschillen

Een ander verschil zit in de syntaxis:

JSON_QUERY ( expression [ , path ] )
JSON_VALUE ( expression , path )

Kijk naar de JSON_QUERY() syntaxis. Die vierkante haken rond het path argument betekent dat het een optioneel argument is. Dat komt omdat deze functie indien nodig een heel JSON-document kan retourneren.

Het padargument is echter een verplicht argument bij gebruik van de JSON_VALUE() functie. U moet dus beide argumenten opgeven wanneer u deze functie gebruikt.

Retourwaarden

En nog een verschil zit in hun retourwaarden.

  • JSON_QUERY() retourneert een JSON-fragment van het type nvarchar(max)
  • JSON_VALUE() retourneert een enkele tekstwaarde van het type nvarchar(4000)

Voorbeeld 1 – Een scalaire waarde extraheren

Hier is een voorbeeld om het verschil tussen deze functies te demonstreren bij het extraheren van een scalaire waarde.

SELECT 
  JSON_VALUE('{"Name": "Homer"}', '$.Name') AS 'JSON_VALUE',
  JSON_QUERY('{"Name": "Homer"}', '$.Name') AS 'JSON_QUERY';

Resultaat:

+--------------+--------------+
| JSON_VALUE   | JSON_QUERY   |
|--------------+--------------|
| Homer        | NULL         |
+--------------+--------------+

Dus beide functies proberen dezelfde waarde uit het JSON-document te halen, maar slechts één slaagt:JSON_VALUE() . Dit komt omdat de waarde die ze proberen te extraheren een scalaire waarde is. Kortom, een scalaire waarde is één gegevenseenheid. Dit kan een tekstreeks of een cijfer zijn. Maar het kan geen object of array zijn.

Voorbeeld 2 – Een array extraheren

In dit voorbeeld proberen beide functies een hele array te extraheren.

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';

Resultaat:

+--------------+----------------------------------------+
| JSON_VALUE   | JSON_QUERY                             |
|--------------+----------------------------------------|
| NULL         | ["Eating", "Sleeping", "Base Jumping"] |
+--------------+----------------------------------------+

In dit geval is alleen de JSON_QUERY() functie slaagt.

Voorbeeld 3 – Een array-item extraheren

Dit voorbeeld is vergelijkbaar met het vorige, behalve dat we in plaats van te proberen de hele array te extraheren, maar één item uit de array willen.

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';

Resultaat:

+--------------+--------------+
| JSON_VALUE   | JSON_QUERY   |
|--------------+--------------|
| Base Jumping | NULL         |
+--------------+--------------+

Dus deze keer JSON_VALUE() is de winnaar.

Voorbeeld 4 – Een object extraheren

Laten we een heel object proberen.

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';

Resultaat:

+--------------+--------------+
| JSON_VALUE   | JSON_QUERY   |
|--------------+--------------|
| NULL         | {    
       "Name": "Homer Simpson",
       "Hobbies": ["Eating", "Sleeping", "Base Jumping"]  
    }              |
+--------------+--------------+

En JSON_QUERY() wint.

(Excuseer de opmaak, dit is hoe mijn MSSQL-opdrachtregelprogramma de resultaten retourneert).

Voorbeeld 5 – Pak het hele JSON-document uit

Laten we het hele JSON-document proberen.

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';

Resultaat:

+--------------+--------------+
| JSON_VALUE   | JSON_QUERY   |
|--------------+--------------|
| NULL         | {
    "Cities": [
        {
            "Name": "Kabul",
            "CountryCode": "AFG",
            "District": "Kabol",
            "Population": 1780000
        },
        {
            "Name": "Qandahar",
            "CountryCode": "AFG",
            "District": "Qandahar",
            "Population": 237500
        }
    ]
}              |
+--------------+--------------+

Dus JSON_QUERY() is de enige die het hele document kan retourneren.

Voorbeeld 6 – Weglaten van het pad

Een ander verschil tussen deze twee functies is dat het padargument optioneel is bij gebruik van JSON_QUERY() . Als u dit weglaat, wordt het hele JSON-document geretourneerd.

U kunt dit argument niet weglaten bij gebruik van JSON_VALUE() , omdat het een verplicht argument is. Dit is waarschijnlijk te wijten aan het feit dat de functie alleen een scalaire waarde kan retourneren. Als het eerste argument alleen uit een scalaire waarde zou bestaan, zou het geen geldige JSON zijn.

Hoe dan ook, hier is een voorbeeld van het weglaten van het padargument van JSON_QUERY() :

SELECT JSON_QUERY('{"Name": "Homer"}') AS 'Result';

Resultaat:

+-------------------+
| Result            |
|-------------------|
| {"Name": "Homer"} |
+-------------------+

En dit is wat er gebeurt als we die truc proberen met JSON_VALUE() :

SELECT JSON_VALUE('{"Name": "Homer"}') AS 'Result';

Resultaat:

Msg 174, Level 15, State 1, Line 1
The json_value function requires 2 argument(s).

Voorbeeld 7 – Padmodus

In de eerdere voorbeelden, wanneer een functie het opgegeven pad niet aankon, retourneerde deze NULL . Dit komt omdat al deze voorbeelden werden uitgevoerd in de lax-modus (de standaardmodus).

Als we ze in de strikte modus hadden uitgevoerd, zouden we in plaats daarvan een foutmelding hebben gekregen. Om de padmodus expliciet te specificeren, voegt u deze toe voor het dollarteken (en laat u een spatie ertussen).

Hier is een voorbeeld van wat er gebeurt als je een ongeldig pad opgeeft in de strikte modus:

SELECT 
  JSON_VALUE('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_VALUE',
  JSON_QUERY('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_QUERY';

Resultaat:

Msg 13624, Level 16, State 2, Line 1
Object or array cannot be found in the specified JSON path.

  1. MySQL TIMEDIFF() vs TIMESTAMPDIFF():wat is het verschil?

  2. Reset automatische ophogingsteller in postgre

  3. Eenvoudige manier om kolommen en rijen in SQL te transponeren?

  4. Jaren toevoegen aan een datum in PostgreSQL