Зафиксируйте в цикле - PullRequest
       1

Зафиксируйте в цикле

2 голосов
/ 08 июня 2011
declare
type array is table of src%rowtype index by binary_integer;
l_data array ;

begin

loop

  begin
      select * bulk collect into l_data
        from src
       where processed = 'N'
         and rownum < 10
         for update of processed;
      exit when sql%rowcount = 0;
  exception
       when no_data_found then exit;
  end;

for i in 1 .. l_data.count
    loop
        update tgt set x = l_data(i).x , y = l_data(i).y where rowid = l_data(i).tgt_row_id  ;
        update src set processed = 'Y' where tgt_row_id = l_data(i).tgt_row_id;
    end loop;

commit; 



end loop;

end;
/

Я отредактировал код для использования массового сбора, но он просто зависает в 11.2.

SQL> select * from src;

         X Y          TGT_ROW_ID         P
---------- ---------- ------------------ -
         1 ABC        AAAWZDAAEAAAA1EAAA Y
         1 DEF        AAAWZDAAEAAAA1EAAA Y
         2 ABC        AAAWZDAAEAAAA1EAAC Y

SQL> select * from tgt;

         X Y
---------- ----------
         1 ABC
         1
         2 ABC

1 Ответ

1 голос
/ 08 июня 2011

Здесь действительно несколько вопросов.

1) Ошибка в строке 10. Это потому, что вам нужно использовать BULK COLLECT для выбора в массиве:

select x,y,tgt_row_id 
bulk collect into l_data
from src

Однако, поскольку l_data определяется с использованием src%rowtype, вышеработает только если в таблице только 3 столбца x, y, tgt_row_id.При использовании %rowtype на самом деле лучше использовать select *, поскольку оно точно соответствует структуре записи.

2) Ваш цикл никогда не завершается.Вам нужно добавить что-то вроде этого:

loop
  select * bulk collect into l_data
    from src
   where processed = 'N'
     and rownum < 10
     for update of processed;

   exit when sql%rowcount = 0;
   ...
end loop;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...