2017-01-13 2 views
1

Ich habe eine Sammlung von Objekttyp deklariert:Eliminieren von Duplikaten in der Sammlung

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

CREATE TYPE category_tab AS TABLE OF category_type; 
/

Und in der PL/SQL-Code:

v_category_data  category_Tab := category_tab(); 

Nachdem ich v_category_data bevölkern, finde ich es Duplikate. Ich muss sie entfernen. Also, ich habe versucht, mit MULTISET UNION DISTINCT durch diese Arbeit:

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

Allerdings bekomme ich diesen Fehler:

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

Ich versuchte, die MAP-Funktionalität, aber nicht verstehen, wie genau zu verwenden, es, oder wenn es helfen würde.

Kennt jemand eine Möglichkeit, die Duplikate in einer Objektsammlung zu entfernen?

+1

Wie Sie die Sammlung bevölkern - können Sie nicht die Duplikate werden in erster Linie eingeschlossen verhindern? –

+0

HI, ich denke ** in ** auswählen ist hier einfacher. Wählen Sie distinct einfach in Ihre Variable – hmmftg

+1

Schauen Sie sich die SET-Funktion an: https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions144.htm#i1269374 –

Antwort

0

multiset union distinct müssen die Elemente der Kollektion vergleichbar sein. In Ihrem Fall sind die Elemente PL/SQL-Datensätze, die leider keine vergleichbaren Datenstrukturen sind (d. H. PL/SQL bietet keinen eingebauten Mechanismus zum Vergleichen von PL/SQL-Datensätzen).

multiset union funktioniert, weil es die Elemente nicht vergleichen muss.

Wenn Sie aus irgendeinem Grund distinct nicht verwenden möchten, wenn Sie Ihre v_category_data-Auflistung auffüllen, rate ich Ihnen, das zu tun, was ich unten geschrieben habe. Auswahl aus der Sammlung und Verwendung von distinct für die Spalten.

Dies ist der Teil, das Sie interessiert:

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

Und das ist der gesamte Code, mit dem ich überprüft.

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; 
0

Siehe unten, wie wir dies erreichen können:

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; 

Ausgabe

SQL>/
*********First Collection Elements************** 
AB1 
AB1 
BC2 
*********Second Collection Elements************** 
AB1 
BC2 

PL/SQL procedure successfully completed. 
Verwandte Themen