Как я могу вставить элемент во вложенную таблицу, только если он не существует? - PullRequest
1 голос
/ 05 октября 2011

Я хочу иметь вложенную таблицу, содержащую пользовательские объекты, добавляя их один за другим из нескольких курсоров.Но я не хочу иметь дубликаты в таблице.Как мне этого добиться?

Вот как я добавляю элементы в таблицу:

create type recipient as object (firstname varchar2, lastname varchar2, email varchar2);

declare type recipients_list is table of recipient;
rec recipients_list := recipients_list();

cursor admins is
    select firstname, lastname, email
    from users
    where profile_id = 1;

cursor operators is
    select firstname, lastname, email
    from users
    where operator = 1;

-- an user may be both admin and operator

....

for to_email in admins 
loop
    rec.extend;
    rec(rec.last) := recipient(to_email.firstname, to_email.lastname, to_email.email);
end loop;

for to_email in operators 
loop
    rec.extend;
    rec(rec.last) := recipient(to_email.firstname, to_email.lastname, to_email.email);
end loop;

Обратите внимание, что это всего лишь пример, и в данном конкретном случае выбор может быть изменен вЧтобы иметь только один курсор.Но в моем приложении все иначе.Спасибо!

1 Ответ

5 голосов
/ 05 октября 2011

Если вы используете Oracle 10g или выше, есть несколько простых способов решить эту проблему.

Можно использовать существующий код, а в цикле OPERATORS оператор MEMBER OF проверить, существует ли он уже в коллекции.

Однако, более простой подход - определить три коллекции. Используйте массовый сбор, чтобы заполнить две коллекции полным набором записей из каждого запроса, а затем используйте третью коллекцию, чтобы отфильтровать любые дубликаты.

Что-то вроде этого:

declare 

    type recipients_list is table of recipient;
    recs recipients_list := recipients_list();
    admins recipients_list := recipients_list();
    operators recipients_list := recipients_list();

begin

    select firstname, lastname, email
    bulk collect into admins
    from users
    where profile_id = 1;

    select firstname, lastname, email
    bulk collect into operators
    from users
    where operator = 1;

    recs := admins multiset union distinct operators;

end;
/

«Можно ли иметь несколько союзов?»

Это наверняка возможно. Я не знаю, есть ли максимум, но если он будет, это будет большое число. Я обнаружил, что ограничения в Oracle имеют тенденцию быть щедрыми; если мы столкнемся с ограничениями, возможно, есть лучший способ сделать что угодно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...