Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

JSON_QUERY() vs. JSON_VALUE() in SQL Server:Was ist der Unterschied?

Zwei der vielen in SQL Server verfügbaren T-SQL-Funktionen sind JSON_QUERY() und JSON_VALUE() . Diese Funktionen können verwendet werden, um Daten aus JSON-Dokumenten zu extrahieren.

Ihre allgemeine Syntax ist ähnlich, und auf den ersten Blick könnte man denken, dass sie genau dasselbe tun, aber das tun sie nicht. Bei der Arbeit mit JSON und SQL Server ist definitiv Platz für beide Funktionen.

Dieser Artikel befasst sich mit dem Unterschied zwischen JSON_QUERY() und JSON_VALUE() .

Der Unterschied

Diese beiden Funktionen haben leicht unterschiedliche Definitionen, eine leicht unterschiedliche Syntax und ihre Rückgabewerte sind leicht unterschiedlich.

Definitionen

So werden die beiden Funktionen definiert:

JSON_QUERY()
Extrahiert ein Objekt oder ein Array aus einer JSON-Zeichenfolge.
JSON_VALUE()
Extrahiert einen Skalarwert aus einer JSON-Zeichenfolge.

Der Unterschied zwischen diesen beiden Funktionen besteht also darin, was sie extrahieren. Einer extrahiert ein Objekt oder ein Array, der andere einen Skalarwert.

Syntaxunterschiede

Ein weiterer Unterschied liegt in der Syntax:

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

Sehen Sie sich JSON_QUERY() an Syntax. Diese eckigen Klammern um den path Argument bedeutet, dass es sich um ein optionales Argument handelt. Das liegt daran, dass diese Funktion bei Bedarf ein ganzes JSON-Dokument zurückgeben kann.

Das Pfadargument ist jedoch ein erforderliches Argument, wenn JSON_VALUE() verwendet wird Funktion. Sie müssen also beide Argumente angeben, wenn Sie diese Funktion verwenden.

Rückgabewerte

Und ein weiterer Unterschied liegt in ihren Rückgabewerten.

  • JSON_QUERY() gibt ein JSON-Fragment vom Typ nvarchar(max) zurück
  • JSON_VALUE() gibt einen einzelnen Textwert vom Typ nvarchar(4000) zurück

Beispiel 1 – Extrahieren Sie einen Skalarwert

Hier ist ein Beispiel, um den Unterschied zwischen diesen Funktionen zu demonstrieren, wenn versucht wird, einen Skalarwert zu extrahieren.

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

Ergebnis:

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

Beide Funktionen versuchen also, denselben Wert aus dem JSON-Dokument zu extrahieren, aber nur eine ist erfolgreich:JSON_VALUE() . Dies liegt daran, dass der Wert, den sie zu extrahieren versuchen, ein Skalarwert ist. Im Grunde ein skalarer Wert ist eine Dateneinheit. Dies kann eine Zeichenfolge oder eine Zahl sein. Aber es kann kein Objekt oder Array sein.

Beispiel 2 – Ein Array extrahieren

In diesem Beispiel versuchen beide Funktionen, ein ganzes Array zu extrahieren.

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

Ergebnis:

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

In diesem Fall nur die JSON_QUERY() Funktion erfolgreich.

Beispiel 3 – Extrahieren Sie ein Array-Element

Dieses Beispiel ähnelt dem vorherigen, außer dass wir nicht versuchen, das gesamte Array zu extrahieren, sondern nur ein einzelnes Element aus dem Array wollen.

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

Ergebnis:

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

Also dieses Mal JSON_VALUE() ist der Gewinner.

Beispiel 4 – Ein Objekt extrahieren

Versuchen wir es mit einem ganzen 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';

Ergebnis:

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

Und JSON_QUERY() gewinnt.

(Entschuldigen Sie die Formatierung, so gibt mein MSSQL-Befehlszeilentool die Ergebnisse zurück).

Beispiel 5 – Extrahieren Sie das gesamte JSON-Dokument

Versuchen wir es mit dem gesamten JSON-Dokument.

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

Ergebnis:

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

Also JSON_QUERY() ist der einzige, der das gesamte Dokument zurückgeben kann.

Beispiel 6 – Weglassen des Pfads

Ein weiterer Unterschied zwischen diesen beiden Funktionen besteht darin, dass das Pfadargument optional ist, wenn JSON_QUERY() verwendet wird . Wenn Sie dies weglassen, wird das gesamte JSON-Dokument zurückgegeben.

Sie können dieses Argument nicht weglassen, wenn Sie JSON_VALUE() verwenden , da es sich um ein erforderliches Argument handelt. Dies liegt wahrscheinlich daran, dass die Funktion nur einen Skalarwert zurückgeben kann. Wenn das erste Argument nur aus einem Skalarwert bestünde, wäre es kein gültiges JSON.

Wie auch immer, hier ist ein Beispiel für das Weglassen des Pfadarguments von JSON_QUERY() :

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

Ergebnis:

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

Und das passiert, wenn wir diesen Trick mit JSON_VALUE() versuchen :

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

Ergebnis:

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

Beispiel 7 – Pfadmodus

Wenn in den vorherigen Beispielen eine Funktion den angegebenen Pfad nicht verarbeiten konnte, gab sie NULL zurück . Dies liegt daran, dass alle diese Beispiele im Lax-Modus (dem Standardmodus) ausgeführt wurden.

Wenn wir sie im strikten Modus ausführen würden, hätten wir stattdessen einen Fehler erhalten. Um den Pfadmodus explizit anzugeben, fügen Sie ihn einfach vor dem Dollarzeichen hinzu (und lassen Sie ein Leerzeichen dazwischen).

Hier ist ein Beispiel dafür, was passiert, wenn Sie im strikten Modus einen ungültigen Pfad angeben:

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

Ergebnis:

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