合并oracle中的集合?

时间:2014-10-16 00:27:43

标签: sql oracle plsql

我需要合并两个集合。我知道可以合并两个表,但不确定集合。 合并馆藏的最佳方式是什么? 下面说的是示例代码

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

我有两个列表/集合

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 

我想基于id匹配list1和list2并添加val else insert。 我想在list3中如下所示。

list3 
id val 
1 400 
2 200 
3 300
4 500

有人可以为此提供示例代码吗?

2 个答案:

答案 0 :(得分:2)

集合可以与SQL合并。创建集合,将集合转换为表,连接表,然后将表转换回集合。

第一次遇到这种由内向外的内联视图逻辑流程时,这可能很棘手。特别是对于高级功能,如对象类型,交叉连接和转换/收集。这些步骤都有编号和字母,以帮助您跟踪。以这种方式构建查询的优点是调试起来要容易得多。从中间开始,在IDE中突出显示并运行查询块,并继续向外移动,直到您理解整个查询。

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

答案 1 :(得分:2)

使用TABLE()运算符,您可以使用SQL语句操作集合,就像它们是数据库表一样。例如,在您的情况下,执行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);

鉴于您的两个样本列表,这将存储在list3中:

1 400
2 200
3 300
4 500

要测试的完整代码:

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;