Удалить дубликат коллекции в oracle - PullRequest
0 голосов
/ 23 января 2020

У меня есть этот тип в моем пакете:

TYPE LIST_A_TYPE TABLE OF TABLE_A%ROWTYPE;

Затем у меня есть эта процедура, где я заполняю эту коллекцию, зацикливая таблицу:

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:

После этого l oop, Моя коллекция полна l_list_a.

Мне нужна процедура для удаления дубликатов этого списка на основе некоторых столбцов его определения (таблица).

I думал использовать функцию SET, но продолжает выдавать ошибку.

Таблица TABLE_A имеет 30 столбцов. У меня есть «ключ» из 5 столбцов, чтобы определить, можно ли дублировать запись или нет ...

Какие-нибудь советы?

Спасибо

1 Ответ

0 голосов
/ 23 января 2020

Как правило, вы должны создать MAP MEMBER FUNCTION для записи. Я не думаю, что это может быть основано на TABLE_A%ROWTYPE, вы должны определить тип вручную.

См. Этот пример. Объект STATIC_ROUTE имеет 6 атрибутов, а ключ IP_ADDRESS,NETWORK_MASK,NEXT_HOP.

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
/

Теперь вы можете использовать функцию SET для переменных STATIC_ROUTES.

Однако вы должны попытаться получить результат в одном заявлении SLQ. Это может быть похоже на это:

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