Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Analisar Json usando Oracle SQL - JSON_TABLE


Você parece querer uma junção cruzada dos valores da matriz (agrupados por rownum e name ). Esta não é uma estrutura JSON padrão, portanto, você não deve esperar poder fazer isso com um único aplicativo de json_table .

Aqui está uma maneira de fazer isso com duas chamadas para json_table . Na primeira chamada, você usa um caminho aninhado para obter apenas os nomes, mas ainda mantém as matrizes de endereços. Em uma segunda chamada, você descompacta os endereços, separadamente para cada linha produzida pela primeira chamada.

Observe o uso de uma dica do otimizador no select externo . Isso é necessário, pois sem ele o otimizador tentará um "desaninhamento" ilegal da junção lateral (outer apply ) e, em seguida, lançar um erro, em vez de deixar a consulta como está. (Este é um hábito muito comum e irritante do otimizador:ele tenta algo que é inválido e depois reclama.)

Além disso, rownum é uma palavra-chave reservada - você não pode usá-la como um nome de coluna na saída. (Tecnicamente você pode, com trabalho adicional, mas é melhor acreditar que você não pode.)
with
  t as (
    select * 
    from   json_Table(
'{
 "Rownum": "1",
 "Name": "John",
 "AddressArray":["Address1", "Address2"],
 "TextObj":[{"mName" : "Carol","lName" : "Cena"},
            {"mName" : "Mark","lName" : "Karlo"}
           ]
}', 
           '$' columns (
                 rownr        number                     path '$.Rownum', 
                 name         varchar2(100)              path '$.Name', 
                 addressArray varchar2(4000) format json path '$.AddressArray',
                 nested path '$.TextObj[*]'
                   columns  (mName varchar2(100) path '$.mName',
                             lName varchar2(100) path '$.lName'
                            )
               )
           )
  )
select /*+ no_query_transformation */ rownr, name, mname, lname, address
from t
     outer apply
     json_table (t.addressArray, '$[*]'
                   columns (address varchar2(10) path '$')
     )
;

Resultado:
ROWNR NAME   MNAME  LNAME  ADDRESS   
----- ------ ------ ------ ----------
    1 John   Carol  Cena   Address1  
    1 John   Carol  Cena   Address2  
    1 John   Mark   Karlo  Address1  
    1 John   Mark   Karlo  Address2