2014-10-16 13 views
5

Ho bisogno di unire due collezioni. So che due tabelle possono essere unite, ma non sono sicure delle collezioni. Qual è il modo migliore per unire le raccolte? Dire sotto è il codice di esempioUnisci raccolte in oracle?

------------ 
CREATE OR REPLACE TYPE obj_test AS OBJECT(
id number(9), 
val number (9) 
) 
/

CREATE OR REPLACE TYPE obj_test_list AS TABLE OF obj_test 
/

Ho due liste/collezioni

list1 obj_test_list ; 
list2 obj_test_list ; 
list3 obj_test_list ; 


list1   
id val 
1 100 
2 200 
3 300 


list2  
id val 
1 300 
4 500 

voglio abbinare Lista1 e Lista2 sulla base di id e aggiungere val altro inserire. Lo voglio in list3 come segue.

list3 
id val 
1 400 
2 200 
3 300 
4 500 

Qualcuno può fornire un codice di esempio per questo?

risposta

2

Utilizzando l'operatore TABLE(), è possibile manipolare le vostre collezioni utilizzando le istruzioni SQL, proprio come se fossero tabelle DB. Nel tuo caso, ad esempio, per eseguire un FULL OUTER JOIN:

SELECT obj_test(id,NVL(T1.val,0)+NVL(T2.val,0)) 
     BULK COLLECT INTO list3 
     FROM TABLE(list1) T1 FULL OUTER JOIN TABLE(list2) T2 USING(id); 

dato la vostra lista di due campioni, questo memorizzerà in list3:

1 400 
2 200 
3 300 
4 500 

codice completo alla prova:

DECLARE 

    list1 obj_test_list := obj_test_list(obj_test(1,100),obj_test(2,200),obj_test(3,300)); 
    list2 obj_test_list := obj_test_list(obj_test(1,300),obj_test(4,500)); 
    list3 obj_test_list; 
    indx PLS_INTEGER; 

BEGIN 

    SELECT obj_test(id,NVL(T1.val,0)+NVL(T2.val,0)) 
      BULK COLLECT INTO list3 
      FROM TABLE(list1) T1 FULL OUTER JOIN TABLE(list2) T2 USING(id); 

    indx := list3.FIRST; 
    WHILE(indx IS NOT NULL) 
    LOOP 
     DBMS_OUTPUT.PUT(list3(indx).id); 
     DBMS_OUTPUT.PUT(' '); 
     DBMS_OUTPUT.PUT_LINE(list3(indx).val); 
     indx := list3.NEXT(indx); 
    END LOOP; 

END; 
2

Le raccolte possono essere unite con SQL. Creare le raccolte, convertire le raccolte in tabelle, unire le tabelle e quindi riconvertire le tabelle in una raccolta.

Può essere difficile la prima volta che si incontra questo flusso logico di visualizzazione in-out. Soprattutto con funzioni avanzate come tipi di oggetti, cross join e cast/collect. I passaggi sono numerati e contrassegnati per aiutarti a tenere traccia. Il vantaggio di creare una query in questo modo è che è molto più semplice eseguire il debug. Inizia dalla metà, evidenzia ed esegui un blocco di query nel tuo IDE e continua a spostarti fino a comprendere l'intera query.

--#4: Create new collection of results. 
select cast(collect(obj_test(id, val)) as obj_test_list) 
from 
(
    --#3: Join lists and add results - returns results in normalized format. 
    select 
    coalesce(list_1_normalized.id, list_2_normalized.id) id, 
    coalesce(list_1_normalized.val, 0) + coalesce(list_2_normalized.val, 0) val 
    from 
    (
    --#2a: List 1 normalized. 
    select id, val 
    from 
    (
     --#1a: List 1 objects. 
     select obj_test_list(obj_test(1,100),obj_test(2,200),obj_test(3,300))list 
     from dual 
    ) list_1_objects 
    cross join table(list_1_objects.list) 
) list_1_normalized 
    full outer join 
    (
    --#2b: List 2 normalized. 
    select id, val 
    from 
    (
     --#1b: List 2 objects. 
     select obj_test_list(obj_test(1,300),obj_test(4,500))list 
     from dual 
    ) list_2_objects 
    cross join table(list_2_objects.list) 
) list_2_normalized 
    on list_1_normalized.id = list_2_normalized.id 
);