I have this type in my package:
TYPE LIST_A_TYPE TABLE OF TABLE_A%ROWTYPE;
Then I have this procedure where I populate this collection looping a table:
procedure load_me as l_list_a LIST_A_TYPE l_rec_a TABLE_A%ROWTYPE; begin -- init collection l_list_a := LIST_A_TYPE (); for rec in (select * from table_b) loop -- do stuff that returns a TABLE_A rowtype l_rec_a := populate_a(rec) l_list_a.extend(); l_list_a(l_list_a.count) := l_rec_a ; end loop; end load_me:
After this loop, I have my collection full of l_list_a
.
I need a procedure to remove duplicates of this list based on some columns of its definition (table).
I thought to use the SET function but keeps giving me an error.
The table TABLE_A has 30 columns. I got a ‘key’ of 5 columns to determine if the record could be duplicated or not…
Any tips?
Thanks
Advertisement
Answer
In general you have to create a MAP MEMBER FUNCTION
for the record. I don’t think it can be based on TABLE_A%ROWTYPE
, you have to define the type manually.
See this example. Object STATIC_ROUTE
has 6 attributes and IP_ADDRESS,NETWORK_MASK,NEXT_HOP
is the key.
CREATE OR REPLACE TYPE STATIC_ROUTE AS OBJECT ( ROUTE_INDEX NUMBER, IP_ADDRESS VARCHAR2(15), NETWORK_MASK VARCHAR2(15), NEXT_HOP VARCHAR2(15), REDISTRIBUTE VARCHAR2(5), ROUTE_METRIC NUMBER, MAP MEMBER FUNCTION getId RETURN VARCHAR2) / CREATE OR REPLACE TYPE BODY STATIC_ROUTE IS MAP MEMBER FUNCTION getId RETURN VARCHAR2 IS BEGIN RETURN SELF.IP_ADDRESS||'-'||SELF.NETWORK_MASK||'-'||SELF.NEXT_HOP; END; END; / CREATE OR REPLACE TYPE STATIC_ROUTES AS TABLE OF STATIC_ROUTE /
Now you can use SET
function on STATIC_ROUTES variables.
However, you should try to get the result in a single SLQ statement. It could be similar to this one:
WITH t AS ( SELECT DISTINCT id_col_1, id_col_2, id_col_3, id_col_4, id_col_5, FIRST_VALUE(col_6) OVER (PARTITION BY id_col_1, id_col_2, id_col_3, id_col_4, id_col_5 ORDER BY ROWID) col_6, FIRST_VALUE(col_7) OVER (PARTITION BY id_col_1, id_col_2, id_col_3, id_col_4, id_col_5 ORDER BY ROWID) col_7, FIRST_VALUE(col_8) OVER (PARTITION BY id_col_1, id_col_2, id_col_3, id_col_4, id_col_5 ORDER BY ROWID) col_8, ... FIRST_VALUE(col_30) OVER (PARTITION BY id_col_1, id_col_2, id_col_3, id_col_4, id_col_5 ORDER BY ROWID) col_30 FROM TABLE_A) SELECT LIST_A_TYPE(id_col_1, id_col_2, id_col_3, id_col_4, id_col_5, id_col_6, ... col_30) BULK COLLECT INTO l_list_a FROM t;