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()
.