I need to merge two collections. I know two tables can be merged , but not sure of collections. What is the best way to merge collections ? Say below is the sample code
------------
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
/
I have two lists/collections
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 
I want to match list1 and list2 based on id and add val else insert. I want it in list3 as follows.
list3 
id val 
1 400 
2 200 
3 300
4 500
Can someone give a sample code for this?
Using the TABLE() operator, you can manipulate your collections using SQL statements just like if they were DB tables. In your case, for example, to perform a 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);
Given your two sample list, this will store in list3:
1 400
2 200
3 300
4 500
Full code to test:
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;
                        Collections can be merged with SQL. Create the collections, convert the collections into tables, join the tables, and then convert the tables back into a collection.
It can be tricky the first time you encounter this inside-out inline view logic flow. Especially with advanced features like object types, cross joins, and cast/collect. The steps are numbered and lettered to help you keep track. The advantage to building a query this way is that it's much easier to debug. Start from the middle, highlight and run a query block in your IDE, and keep moving out until you understand the whole 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
);
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With