如何比较Oracle中的复杂集合?

Posted

技术标签:

【中文标题】如何比较Oracle中的复杂集合?【英文标题】:How to compare complex collections in Oracle? 【发布时间】:2012-09-07 19:12:22 【问题描述】:

假设我有两个表类型(对象类型表),我想比较它们是否相等...

对象类型有多个字段,例如 integervarchar2date

我已经看到人们使用MULTISET EXCEPT 以便在INTEGER 的两个表上有效地执行MINUS 的示例。

但这不适用于两个复杂对象类型的表。

我还看到在使用SET 运算符时提到使用MAP MEMBER FUNCTION 以使复杂的集合工作,但没有提到MULTISET 功能。

我目前比较相等性的方法是使用表类型 1 (TT1) 和表类型 2 (TT2),如果 TT1 MINUS TT2 = 0 AND TT2 MINUS TT1 = 0 则说它们相等。但是这里我只是从两个表中为 MINUS 选择 PK,我还希望能够比较多个字段。

我希望MULTISET 更快?

谢谢。

【问题讨论】:

【参考方案1】:

是的,您可以使用MAP MEMBER FUNCTION 来支持比较嵌套的类型表。

--#1: Create object
create or replace type type1 is object
(
    a integer,
    b varchar2(100),
    c date,
    map member function compare return raw
);
/

--#2: Create map function for comparisons.
--Returns the concatenated RAW of all attributes.
--Note that this will consider NULLs to be equal!
create or replace type body type1 as
    map member function compare return raw is
    begin
        return
            utl_raw.cast_to_raw(to_char(a))||
            utl_raw.cast_to_raw(b)||
            utl_raw.cast_to_raw(to_char(c, 'DD-MON-YYYY HH24:MI:SS'));

    end;
end;
/

--#3: Create nested table of the types
create or replace type type1_nt is table of type1;
/

--#4: Compare.
--You could use MULTISET, but it's easier to use regular operators like "<>" "and =".
declare
    tt1 type1_nt := type1_nt(type1(0, 'A', date '2000-01-01'),
                             type1(0, 'A', date '2000-01-01'));
    tt2 type1_nt := type1_nt(type1(0, 'B', date '2000-01-01'),
                             type1(0, 'B', date '2000-01-01'));
    tt3 type1_nt := type1_nt(type1(0, 'B', date '2000-01-01'),
                             type1(0, 'B', date '2000-01-01'));
begin
    if tt1 <> tt2 and tt2 = tt3 then
        dbms_output.put_line('Pass');
    else
        dbms_output.put_line('Fail');
    end if;
end;
/

我不知道这是否比手动比较每个属性更快。但我猜差异不会很大。

【讨论】:

以上是关于如何比较Oracle中的复杂集合?的主要内容,如果未能解决你的问题,请参考以下文章

集合的复杂排序

函数如何使用 oracle 中的集合返回第二个和第四个值?答案是 42 和 46

plsql-Oracle 集合

如何比较两个通用集合[重复]

如何保证集合是线程安全的?

如何将单个元素与集合或列表中的任何元素进行比较[重复]