Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

JSON_QUERY() vs JSON_VALUE() in SQL Server:qual è la differenza?

Due delle numerose funzioni T-SQL disponibili in SQL Server sono JSON_QUERY() e JSON_VALUE() . Queste funzioni possono essere utilizzate per estrarre dati da documenti JSON.

La loro sintassi generale è simile e, a prima vista, potresti pensare che facciano esattamente la stessa cosa, ma non lo fanno. C'è sicuramente un posto per entrambe le funzioni quando si lavora con JSON e SQL Server.

Questo articolo esamina la differenza tra JSON_QUERY() e JSON_VALUE() .

La differenza

Queste due funzioni hanno definizioni leggermente diverse, una sintassi leggermente diversa e i loro valori di ritorno sono leggermente diversi.

Definizioni

Ecco come vengono definite le due funzioni:

JSON_QUERY()
Estrae un oggetto o un array da una stringa JSON.
JSON_VALUE()
Estrae un valore scalare da una stringa JSON.

Quindi la differenza tra queste due funzioni è ciò che estraggono. Uno estrae un oggetto o un array, l'altro estrae un valore scalare.

Differenze di sintassi

Un'altra differenza è nella sintassi:

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

Guarda il JSON_QUERY() sintassi. Quelle parentesi quadre intorno al path argomento significa che è un argomento facoltativo. Questo perché questa funzione può restituire un intero documento JSON, se necessario.

Tuttavia, l'argomento del percorso è un argomento obbligatorio quando si utilizza JSON_VALUE() funzione. Quindi devi fornire entrambi gli argomenti quando usi questa funzione.

Valori di ritorno

E un'altra differenza è nei loro valori di ritorno.

  • JSON_QUERY() restituisce un frammento JSON di tipo nvarchar(max)
  • JSON_VALUE() restituisce un valore di testo singolo di tipo nvarchar(4000)

Esempio 1 – Estrarre un valore scalare

Ecco un esempio per dimostrare la differenza tra queste funzioni quando si tenta di estrarre un valore scalare.

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

Risultato:

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

Quindi entrambe le funzioni stanno cercando di estrarre lo stesso valore dal documento JSON, ma solo una riesce:JSON_VALUE() . Questo perché il valore che stanno cercando di estrarre è un valore scalare. Fondamentalmente, un valore scalare è un'unità di dati. Potrebbe essere una stringa di testo o un numero. Ma non può essere un oggetto o un array.

Esempio 2:estrazione di un array

In questo esempio, entrambe le funzioni tentano di estrarre un intero 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';

Risultato:

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

In questo caso, solo JSON_QUERY() la funzione riesce.

Esempio 3:estrazione di un elemento dell'array

Questo esempio è simile al precedente, tranne per il fatto che invece di cercare di estrarre l'intero array, vogliamo solo un singolo elemento dall'array.

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

Risultato:

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

Quindi questa volta JSON_VALUE() è il vincitore.

Esempio 4 – Estrarre un oggetto

Proviamo per un intero oggetto.

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

Risultato:

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

E JSON_QUERY() vince.

(Scusate la formattazione, ecco come il mio strumento da riga di comando MSSQL restituisce i risultati).

Esempio 5:estrarre l'intero documento JSON

Proviamo per l'intero documento JSON.

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

Risultato:

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

Quindi JSON_QUERY() è l'unico che può restituire l'intero documento.

Esempio 6 – Ometti il ​​percorso

Un'altra differenza tra queste due funzioni è che l'argomento del percorso è facoltativo quando si utilizza JSON_QUERY() . Se lo ometti, viene restituito l'intero documento JSON.

Non puoi omettere questo argomento quando usi JSON_VALUE() , in quanto è un argomento obbligatorio. Ciò è probabilmente dovuto al fatto che la funzione può restituire solo un valore scalare. Se il primo argomento fosse costituito solo da un valore scalare, non sarebbe un JSON valido.

Ad ogni modo, ecco un esempio di omissione dell'argomento del percorso da JSON_QUERY() :

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

Risultato:

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

Ed ecco cosa succede se proviamo quel trucco con JSON_VALUE() :

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

Risultato:

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

Esempio 7 – Modalità percorso

Negli esempi precedenti, quando una funzione non poteva gestire il percorso fornito, restituiva NULL . Questo perché tutti questi esempi sono stati eseguiti in modalità lassista (la modalità predefinita).

Se li avessimo eseguiti in modalità rigorosa, avremmo invece ricevuto un errore. Per specificare in modo esplicito la modalità del percorso, è sufficiente aggiungerla prima del simbolo del dollaro (e lasciare uno spazio tra di loro).

Ecco un esempio di cosa succede quando fornisci un percorso non valido in modalità rigorosa:

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

Risultato:

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