【问题标题】:Eliminating duplicates in collection消除集合中的重复项
【发布时间】:2017-05-29 10:25:46
【问题描述】:

我有一个声明的对象类型集合:

CREATE TYPE category_type AS OBJECT (
  col1   VARCHAR2(6),
  col2   VARCHAR2(10),
  col3   NUMBER);
/

CREATE TYPE category_tab AS TABLE OF category_type;
/

在 PL/SQL 代码中:

v_category_data     category_Tab := category_tab();

填充 v_category_data 后,我发现有重复项。我需要删除它们。因此,我尝试通过以下方式使用 MULTISET UNION DISTINCT:

v_new_data := v_category_data;
v_new_data := v_new_data MULTISET UNION DISTINCT v_category_data;

但是,我得到了这个错误:

804/17   PLS-00306: wrong number or types of arguments in call to
         'MULTISET_UNION_DISTINCT'

我尝试使用 MAP 功能,但不明白如何使用它,或者它是否有帮助。

有人知道删除对象集合中的重复项的方法吗?

【问题讨论】:

标签: oracle object plsql types


【解决方案1】:

multiset union distinct 要求集合的元素具有可比性。在您的情况下,这些元素是 PL/SQL 记录,遗憾的是它们不是可比较的数据结构(即 PL/SQL 没有提供用于比较 PL/SQL 记录的内置机制)。

multiset union 有效,因为它不需要比较元素。

如果由于某种原因您不想在填充 v_category_data 集合时使用 distinct,那么我建议您按照我在下面写的那样做。从集合中选择并在列上使用 distinct。

这是你感兴趣的部分:

SELECT Category_type(col1, col2, col3) 
bulk   collect INTO v_new_data 
FROM   (SELECT DISTINCT col1, 
                        col2, 
                        col3 
        FROM   TABLE(v_category_data)); 

这是我检查的全部代码。

DECLARE

v_category_data CATEGORY_TAB := Category_tab(); 
v_new_data      CATEGORY_TAB := Category_tab(); 

BEGIN 

--populate the collection with 2 types of duplicates and print them
FOR i IN 1 .. 10 LOOP 
    v_category_data.Extend(); 

    IF i < 4 THEN 
      V_category_data(v_category_data.last) := 
      Category_type('Test', 'Test', 1); 
    ELSE 
      V_category_data(v_category_data.last) := 
      Category_type('Test2', 'Test2', 2); 
    END IF; 
END LOOP; 

FOR i IN v_category_data.first..v_category_data.last LOOP 
    dbms_output.Put_line(V_category_data(i).col1 
                         ||' ' 
                         ||V_category_data(i).col2 
                         ||' ' 
                         ||V_category_data(i).col3); 
END LOOP; 

dbms_output.Put_line('After processing' 
                     ||Chr(10)); 

-- populate your collection using distinct and print the content
SELECT Category_type(col1, col2, col3) 
bulk   collect INTO v_new_data 
FROM   (SELECT DISTINCT col1, 
                        col2, 
                        col3 
        FROM   TABLE(v_category_data)); 

FOR i IN v_new_data.first..v_new_data.last LOOP 
    dbms_output.Put_line(V_new_data(i).col1 
                         ||' ' 
                         ||V_new_data(i).col2 
                         ||' ' 
                         ||V_new_data(i).col3); 
END LOOP; 

END; 

【讨论】:

    【解决方案2】:

    请看下面我们如何做到这一点:

    CREATE TYPE category_type AS OBJECT (
      col1   VARCHAR2(6),
      col2   VARCHAR2(10),
      col3   NUMBER);
    /
    
    CREATE OR REPLACE  TYPE category_tab AS TABLE OF category_type   ;
    /
    
    declare
    
    v_category_data    category_Tab := category_tab();
    v_new_data         category_Tab := category_tab();
    
    begin
    --Defining collection length
    v_category_data.extend(3);
    
    --Populating the collection
    v_category_data(1):= category_type('A','B',1);
    v_category_data(2):= category_type('A','B',1);
    v_category_data(3):= category_type('B','C',2);
    
    dbms_output.put_line('*********First Collection Elements**************');
    for i in 1..v_category_data.count
     loop  
      dbms_output.put_line(v_category_data(i).col1 || v_category_data(i).col2 || v_category_data(i).col3 );
     end loop;
    
    --Way to remove duplicate
     select 
          v_category_data MULTISET UNION DISTINCT category_Tab(category_type('A','B',1))
        into 
          v_new_data 
        from 
      dual;
    
    --Displaying elements of second collection
    dbms_output.put_line('*********Second Collection Elements**************');
    for i in 1..v_new_data.count
     loop
      dbms_output.put_line(v_new_data(i).col1 || v_new_data(i).col2 || v_new_data(i).col3 );
     end loop;
    
    end;
    

    输出

    SQL> /
    *********First Collection Elements**************
    AB1
    AB1
    BC2
    *********Second Collection Elements**************
    AB1
    BC2
    
    PL/SQL procedure successfully completed.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-25
      • 1970-01-01
      • 2019-02-17
      • 2020-06-23
      • 2015-11-24
      • 1970-01-01
      • 1970-01-01
      • 2022-06-17
      相关资源
      最近更新 更多