2015-04-27 20 views
11

Sto cercando di utilizzare le nuove funzionalità JSON introdotte in Oracle 12.1.0.2Cerca una matrice JSON in Oracle

Tuttavia non riesco a trovare un modo per cercare un valore specifico in una matrice dentro il mio Documento JSON.

Si consideri la seguente tabella e dei dati:

create table orders 
(
    id  integer not null primary key, 
    details clob not null check (details is json (strict)) 
); 

insert into orders (id, details) values 
(1, '{"products": [{ "product": 1, "quantity": 5}, {"product": 2, "quantity": 1}], "delivery_address": "My hometown"}'); 

insert into orders (id, details) values 
(2, '{"products": [{ "product": 42, "quantity": 1}, {"product": 10, "quantity": 2}], "comment": "Your website is too slow"}'); 

insert into orders (id, details) values 
(3, '{"products": [{ "product": 543, "quantity": 1}], "discount": "15"}'); 

insert into orders (id, details) values 
(4, '{"products": [{ "product": 738, "quantity": 12}], "discount": "32"}'); 

Ora sto cercando di scrivere una query SQL che restituisce tutti gli ordini, dove il prodotto # 2 è stato ordinato.

Non riesco a utilizzare json_exists perché non consente le espressioni di matrice (e non saprei comunque specificare il valore).

json_value restituisce solo un valore singolo, pertanto non è possibile "iterare" sui valori dell'array.

ho provato:

select * 
from orders o 
where json_value(details, '$.products[*].product') = '2'; 

ma che non ha prodotto nulla.

Ho anche provato json_table, ma che sembra anche a prendere solo il primo elemento dalla matrice:

select * 
from orders o, 
    json_table(o.details, '$' columns (product_id integer path '$.products[*].product')) t 
where t.product_id = 2; 

Ma questo non ha mostrato nulla. A quanto pare la "espansione stella" nel "array_step" non espande i valori nella json_table

Quindi la mia domanda è:

come posso (in base ai dati di esempio di cui sopra) recuperare tutti gli ordini in cui il prodotto con il numero 2 è stato ordinato?

sto essenzialmente cercando l'equivalente a questa domanda Postgres:

select * 
from orders 
where details @> '{"products": [{"product": 2}] }'; 
+0

Abbiamo sperimentato un bug multi-threading quando si esegue la funzione JSON_TABLE. Fondamentalmente, una delle sessioni è stata disconnessa quando si eseguono due JSON_TABLE simultanei. Assicurati di averlo corretto prima di andare all-in con JSON. –

+0

@PeterHenell: grazie per il suggerimento. Attualmente sto solo esplorando le possibilità, ma lo terrò a mente. –

risposta

15

Non ho alcuna installazione di Oracle disponibili in questo momento, ma credo che la prima stringa in json_table dovrebbe essere il percorso alla matrice da cui vogliamo produrre file da. Quindi all'interno di COLUMNS, il percorso deve essere relativo all'array, non alla radice.

Prova questa:

select * 
from orders o, 
    json_table(o.details, '$.products[*]' 
     columns (
       product_id integer path '$.product' 
     ) 
    ) t 
where t.product_id = 2; 
+0

Ah! Questo ha fatto il trucco. –

+0

Possiamo aggiornare un array esistente? Possiamo aggiungere un oggetto prodotto all'array di prodotti dell'ordine con ID 1? – LazyTechie

0

In 12.2 si può fare questo con JSON_EXISTS

SQL> WITH ORDERS as 
    2 (
    3 select 1 as ID, '{"products": [{ "product": 1, "quantity": 5}, {"product": 2, "quantity": 1}], "delivery_address": "My hometown"}' as DETAILS 
    4  from dual 
    5 union all 
    6 select 2 as ID, '{"products": [{ "product": 42, "quantity": 1}, {"product": 10, "quantity": 2}], "comment": "Your website is too slow"}' as DETAILS 
    7  from dual 
    8 union all 
    9 select 3 as ID, '{"products": [{ "product": 543, "quantity": 1}], "discount": "15"}' as DETAILS 
    10  from dual 
    11 union all 
    12 select 4 as ID, '{"products": [{ "product": 738, "quantity": 12}], "discount": "32"}' as DETAILS 
    13  from dual 
    14 ) 
    15 select * 
    16 from ORDERS 
    17 where JSON_EXISTS(DETAILS,'$?(@.products.product == $PRODUCT)' passing 2 as "PRODUCT") 
    18/

     ID 
---------- 
DETAILS 
-------------------------------------------------------------------------------- 
      1 
{"products": [{ "product": 1, "quantity": 5}, {"product": 2, "quantity": 1}], "d 
elivery_address": "My hometown"} 


SQL> 
+0

Actualy json_exist funziona nella stessa fasion in 12.1 ma non usa indexex –

Problemi correlati