Добавление нескольких строк в al oop к выходному параметру - PullRequest
0 голосов
/ 25 января 2020

Мне нужно сделать резервную копию всех записей, которые будут удалены с помощью следующего кода. Для этого я пытаюсь заменить все команды удаления на select * и сохранить его в файл, используя jdb c ResultSet, но я застрял в приведенном ниже фрагменте, где записи помечаются, а затем удаляются в al oop. Я попытался расширить эту логику c с помощью операторов select..in and...exist, но запрос обрабатывается слишком долго и может произойти сбой в работе. Я также пытался использовать sys_refcursor, но проблема в том, что delete находится внутри al oop и курсор не может быть обновлен. Итак, базовое c требование - как я могу сохранить все записи, которые были удалены с помощью следующего кода, в out_parameter и вернуть его. Пожалуйста помоги! Спасибо.

DECLARE 
    CURSOR purger(p_reference IN VARCHAR2) IS
        SELECT DISTINCT id, reference, PARENT, LEVEL
        FROM table ps1
        START WITH ps1.reference = p_reference
        CONNECT BY PRIOR ps1.reference = ps1.parent;
BEGIN
FOR i IN (SELECT DISTINCT reference
                FROM table
                WHERE PARENT IS NULL)
      LOOP
        l_level  := 'N';
        FOR j IN purger(i.reference)
        LOOP
          IF j.level > 1
          THEN
            l_level := 'Y';
          END IF;
        END LOOP;
        IF l_level = 'N'
        THEN
          DELETE FROM tale WHERE reference = i.reference;
        END IF;
        IF l_level = 'Y'
        THEN
          DELETE FROM table
          WHERE id IN (SELECT DISTINCT id
                       FROM table ps1
                       START WITH ps1.reference = i.reference
                       CONNECT BY PRIOR ps1.reference = ps1.parent);
        END IF;
      END LOOP;
END

1 Ответ

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

Объявите коллекцию ваших первичных ключей. Всякий раз, когда вы удаляете строки, храните список идентификаторов во временной коллекции. Добавьте его элементы в основную коллекцию. После всех удалений основная коллекция имеет все значения первичного ключа, которые были удалены. Вы можете вернуть эту коллекцию, выполнить откат и показать строки. Надеюсь, это поможет.

Данные испытаний:

create table test (id, col) as 
  select 1, 'P' from dual union all
  select 2, 'Q' from dual union all
  select 3, 'Z' from dual;

Блок кода:

declare 
  va sys.odcinumberlist := sys.odcinumberlist();
  vb sys.odcinumberlist;
begin
  -- first delete
  delete from test where col in ('Z') returning id bulk collect into vb;
  -- add deleted ids to VA
  for i in 1..vb.count loop va.extend; va(va.last) := vb(i); end loop;

  -- second delete
  delete from test where col in ('P', 'Z') returning id bulk collect into vb;
  -- add deleted ids to VA
  for i in 1..vb.count loop va.extend; va(va.last) := vb(i); end loop;

  -- variable VA has all deleted ids
  -- you can rollback and show deleted rows if you want

  rollback;
  for rec in (select * from test where id in (select * from table(va))) loop
    dbms_output.put_line(rec.id||' '||rec.col);
  end loop;
end;
...