2014-10-16 23 views
5

Potrzebuję scalić dwie kolekcje. Wiem, że dwie tabele mogą być połączone, ale nie są pewne kolekcji. Jaki jest najlepszy sposób łączenia kolekcji? Say poniżej przykładowy kodScal kolekcje w wyroczni?

------------ 
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 
/

Mam dwie listy/Kolekcje

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 

Chcę dopasować lista1 i lista2 podstawie identyfikatora i dodać Val indziej wstawić. Chcę go na liście3 w następujący sposób.

list3 
id val 
1 400 
2 200 
3 300 
4 500 

Może ktoś podać przykładowy kod dla tego?

Odpowiedz

2

pomocą operatora TABLE() można manipulować kolekcji za pomocą SQL tak jak gdyby były one tabele DB. W twoim przypadku, na przykład, aby przeprowadzić 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); 

Biorąc pod uwagę listę dwie próbki, to będzie przechowywać w lista3:

1 400 
2 200 
3 300 
4 500 

pełny kod do testu:

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

Kolekcje można łączyć z SQL. Utwórz kolekcje, przekształć zbiory w tabele, dołącz do tabel, a następnie przekonwertuj tabele z powrotem na kolekcję.

To może być trudne, gdy pierwszy raz natkniesz się na ten logiczny przepływ danych wewnątrz linii. Zwłaszcza w przypadku zaawansowanych funkcji, takich jak typy obiektów, połączenia krzyżowe i odlewanie/zbieranie. Kroki są ponumerowane i oznaczone, aby pomóc Ci śledzić. Zaletą budowania zapytania w ten sposób jest to, że debugowanie jest o wiele łatwiejsze. Zacznij od środka, zaznacz i uruchom blok kwerendy w IDE, i kontynuuj wyprowadzanie, aż zrozumiesz całe zapytanie.

--#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 
);