Oracle 消除集合中的重复项

Oracle 消除集合中的重复项,oracle,object,plsql,types,Oracle,Object,Plsql,Types,我有一个对象类型的声明集合: 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_categor

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

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_数据后,我发现存在重复项。我需要把它们去掉。因此,我尝试与MULTISET UNION合作,不同之处在于:

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'
我尝试使用地图功能,但不知道如何准确地使用它,或者它是否有帮助

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

multiset union distinct要求集合中的元素具有可比性。在您的例子中,元素是PL/SQL记录,不幸的是,它们不是可比较的数据结构,即PL/SQL没有提供用于比较PL/SQL记录的内置机制

多集并集之所以有效,是因为它不需要比较元素

如果由于某种原因,您在填充v_category_数据收集时不想使用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; 
multiset union distinct要求集合的元素具有可比性。在您的例子中,元素是PL/SQL记录,不幸的是,它们不是可比较的数据结构,即PL/SQL没有提供用于比较PL/SQL记录的内置机制

多集并集之所以有效,是因为它不需要比较元素

如果由于某种原因,您在填充v_category_数据收集时不想使用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; 

请参见下面我们如何实现这一目标:

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.

请参见下面我们如何实现这一目标:

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.

你是如何填充这个集合的?难道你不能首先防止重复项被包括在内吗?嗨,我认为这里的选择更容易。只需在变量中选择distinct就可以了看看SET函数:您是如何填充集合的?您不能首先防止重复项被包括在内吗?您好,我认为在这里选择into更容易。只需在变量中选择distinct即可查看SET函数: