Se você estiver tentando extrair valores de um documento JSON, mas um ou mais valores no mesmo nível tiverem chaves duplicadas, poderá ter problemas se tentar extrair esses valores usando
JSON_QUERY() ou JSON_VALUE() . Ambas as funções retornarão apenas o primeiro valor que corresponde ao caminho.
Felizmente, há outra opção.
O
OPENJSON() A função retornará todos os valores de qualquer chave duplicada no mesmo nível. Exemplo
Aqui está um exemplo para demonstrar
OPENJSON() retornando propriedades duplicadas no mesmo nível. DECLARE @json NVARCHAR(4000) = N'{
"dog" : {
"details" : {
"name" : "Fetch",
"name" : "Good Dog",
"sex" : "male"
}
}
}';
SELECT * FROM OPENJSON(@json, '$.dog.details'); Resultado:
+-------+----------+--------+ | key | value | type | |-------+----------+--------| | name | Fetch | 1 | | name | Good Dog | 1 | | sex | male | 1 | +-------+----------+--------+
Este exemplo retorna todos os filhos de
$.dog.details chave. Neste caso, temos duas chaves com o mesmo nome no mesmo nível (o
name chave). Se quisermos retornar apenas os valores dos dois
name keys, poderíamos fazer algo como o seguinte. DECLARE @json NVARCHAR(4000) = N'{
"dog" : {
"details" : {
"name" : "Fetch",
"name" : "Good Dog",
"sex" : "male"
}
}
}';
SELECT value FROM OPENJSON(@json, '$.dog.details')
WHERE [key] = 'name'; Resultado:
+----------+ | value | |----------| | Fetch | | Good Dog | +----------+
JSON_VALUE() &JSON_QUERY()
Como mencionado, ambos
JSON_VALUE() e JSON_QUERY() retorne apenas o primeiro valor que corresponde ao caminho. Portanto, se tentarmos usá-los no documento JSON acima, obteremos os seguintes resultados.
JSON_VALUE()
JSON_VALUE() retorna um valor escalar de uma string JSON, portanto, retornará o seguinte resultado. DECLARE @json NVARCHAR(4000) = N'{
"dog" : {
"details" : {
"name" : "Fetch",
"name" : "Good Dog",
"sex" : "male"
}
}
}';
SELECT JSON_VALUE(@json, '$.dog.details.name') AS [JSON_VALUE]; Resultado:
+--------------+ | JSON_VALUE | |--------------| | Fetch | +--------------+
JSON_QUERY()
JSON_QUERY() extrai um objeto ou uma matriz de uma string JSON, portanto, retornará o seguinte resultado. DECLARE @json NVARCHAR(4000) = N'{
"dog" : {
"details" : {
"name" : "Fetch",
"name" : "Good Dog",
"sex" : "male"
}
}
}';
SELECT JSON_QUERY(@json, '$.dog.details') AS [JSON_QUERY]; Resultado:
+--------------+
| JSON_QUERY |
|--------------|
| {
"name" : "Fetch",
"name" : "Good Dog",
"sex" : "male"
} |
+--------------+ Pelo menos com
JSON_QUERY() conseguimos ver as chaves duplicadas, mas não obtemos seus valores individuais como obtemos com OPENJSON() .