Duas das muitas funções T-SQL disponíveis no SQL Server são
JSON_QUERY() e JSON_VALUE() . Essas funções podem ser usadas para extrair dados de documentos JSON. Sua sintaxe geral é semelhante e, à primeira vista, você pode pensar que eles fazem exatamente a mesma coisa, mas não fazem. Definitivamente, há um lugar para ambas as funções ao trabalhar com JSON e SQL Server.
Este artigo analisa a diferença entre
JSON_QUERY() e JSON_VALUE() . A diferença
Essas duas funções têm definições ligeiramente diferentes, uma sintaxe ligeiramente diferente e seus valores de retorno são ligeiramente diferentes.
Definições
Veja como as duas funções são definidas:
JSON_QUERY()- Extrai um objeto ou uma matriz de uma string JSON.
JSON_VALUE()- Extrai um valor escalar de uma string JSON.
Portanto, a diferença entre essas duas funções é o que elas extraem. Um extrai um objeto ou um array, o outro extrai um valor escalar.
Diferenças de sintaxe
Outra diferença está na sintaxe:
JSON_QUERY ( expression [ , path ] ) JSON_VALUE ( expression , path )
Veja o
JSON_QUERY() sintaxe. Esses colchetes ao redor do path argumento significa que é um argumento opcional. Isso porque essa função pode retornar um documento JSON inteiro, se necessário. No entanto, o argumento de caminho é um argumento obrigatório ao usar o
JSON_VALUE() função. Portanto, você deve fornecer os dois argumentos ao usar esta função. Valores de retorno
E mais uma diferença está em seus valores de retorno.
JSON_QUERY()retorna um fragmento JSON do tiponvarchar(max)JSON_VALUE()retorna um valor de texto único do tiponvarchar(4000)
Exemplo 1 – Extrair um valor escalar
Aqui está um exemplo para demonstrar a diferença entre essas funções ao tentar extrair um valor escalar.
SELECT
JSON_VALUE('{"Name": "Homer"}', '$.Name') AS 'JSON_VALUE',
JSON_QUERY('{"Name": "Homer"}', '$.Name') AS 'JSON_QUERY';
Resultado:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | Homer | NULL | +--------------+--------------+
Portanto, ambas as funções estão tentando extrair o mesmo valor do documento JSON, mas apenas uma consegue:
JSON_VALUE() . Isso ocorre porque o valor que eles estão tentando extrair é um valor escalar. Basicamente, um valor escalar é uma unidade de dados. Pode ser uma sequência de texto ou um número. Mas não pode ser um objeto ou um array. Exemplo 2 – Extrair uma matriz
Neste exemplo, ambas as funções tentam extrair uma matriz inteira.
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';
Resultado:
+--------------+----------------------------------------+ | JSON_VALUE | JSON_QUERY | |--------------+----------------------------------------| | NULL | ["Eating", "Sleeping", "Base Jumping"] | +--------------+----------------------------------------+
Neste caso, apenas o
JSON_QUERY() função for bem-sucedida. Exemplo 3 – Extrair um item de matriz
Este exemplo é semelhante ao anterior, exceto que em vez de tentar extrair todo o array, queremos apenas um único item do 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';
Resultado:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | Base Jumping | NULL | +--------------+--------------+
Desta vez
JSON_VALUE() é o vencedor. Exemplo 4 – Extrair um objeto
Vamos tentar um objeto inteiro.
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';
Resultado:
+--------------+--------------+
| JSON_VALUE | JSON_QUERY |
|--------------+--------------|
| NULL | {
"Name": "Homer Simpson",
"Hobbies": ["Eating", "Sleeping", "Base Jumping"]
} |
+--------------+--------------+
E
JSON_QUERY() vitórias. (Desculpe a formatação, é assim que minha ferramenta de linha de comando MSSQL retorna os resultados).
Exemplo 5 – Extraia todo o documento JSON
Vamos tentar para todo o 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';
Resultado:
+--------------+--------------+
| JSON_VALUE | JSON_QUERY |
|--------------+--------------|
| NULL | {
"Cities": [
{
"Name": "Kabul",
"CountryCode": "AFG",
"District": "Kabol",
"Population": 1780000
},
{
"Name": "Qandahar",
"CountryCode": "AFG",
"District": "Qandahar",
"Population": 237500
}
]
} |
+--------------+--------------+
Então
JSON_QUERY() é o único que pode retornar o documento inteiro. Exemplo 6 – Omitir o caminho
Outra diferença entre essas duas funções é que o argumento path é opcional ao usar
JSON_QUERY() . Se você omitir isso, todo o documento JSON será retornado. Você não pode omitir este argumento ao usar
JSON_VALUE() , pois é um argumento obrigatório. Isso provavelmente se deve ao fato de que a função só pode retornar um valor escalar. Se o primeiro argumento consistisse apenas em um valor escalar, não seria um JSON válido. De qualquer forma, aqui está um exemplo de omissão do argumento path de
JSON_QUERY() :SELECT JSON_QUERY('{"Name": "Homer"}') AS 'Result';
Resultado:
+-------------------+
| Result |
|-------------------|
| {"Name": "Homer"} |
+-------------------+
E aqui está o que acontece se tentarmos esse truque com
JSON_VALUE() :SELECT JSON_VALUE('{"Name": "Homer"}') AS 'Result';
Resultado:
Msg 174, Level 15, State 1, Line 1 The json_value function requires 2 argument(s).
Exemplo 7 – Modo de caminho
Nos exemplos anteriores, quando uma função não conseguia lidar com o caminho fornecido, ela retornava
NULL . Isso ocorre porque todos esses exemplos foram executados no modo lax (o modo padrão). Se os executássemos no modo estrito, teríamos recebido um erro. Para especificar explicitamente o modo de caminho, basta adicioná-lo antes do cifrão (e deixar um espaço entre eles).
Aqui está um exemplo do que acontece quando você fornece um caminho inválido no modo estrito:
SELECT
JSON_VALUE('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_VALUE',
JSON_QUERY('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_QUERY';
Resultado:
Msg 13624, Level 16, State 2, Line 1 Object or array cannot be found in the specified JSON path.