在使用BULK COLLECT处理Oracle(11g)中的记录时,遇到了一个有趣且意外的问题。使用“for update”进行批量收集
下面的代码正在运行大,处理过的所有万美元,外加记录用了一个问题:
-- Define cursor
cursor My_Data_Cur Is
Select col1
,col2
from My_Table_1;
…
-- Open the cursor
open My_Data_Cur;
-- Loop through all the records in the cursor
loop
-- Read the first group of records
fetch My_Data_Cur
bulk collect into My_Data_Rec
limit 100;
-- Exit when there are no more records to process
Exit when My_Data_Rec.count = 0;
-- Loop through the records in the group
for idx in 1 .. My_Data_Rec.count
loop
… do work here to populate a records to be inserted into My_Table_2 …
end loop;
-- Insert the records into the second table
forall idx in 1 .. My_Data_Rec.count
insert into My_Table_2…;
-- Delete the records just processed from the source table
forall idx in 1 .. My_Data_Rec.count
delete from My_Table_1 …;
commit;
end loop;
由于在处理每个组100个记录的结尾(限100),我们只是删除记录读取和处理,我认为将“更新”语法添加到游标定义是一个好主意,以便另一个进程在数据读取和记录被删除的时间之间无法更新任何记录。
所以,我改变了代码的唯一事情是......
cursor My_Data_Cur
is
select col1
,col2
from My_Table_1
for update;
当我这个更改后跑了PL/SQL包,工作只处理100条记录,然后终止。我通过从游标中删除“for update”来确认此更改导致了问题,并且包再次处理源表中的所有记录。
任何想法为什么添加“for update”子句会导致这种行为变化?有关如何解决此问题的任何建议?我将尝试在流程开始时在表上开始一个独占事务,但这不是一个想法解决方案,因为我真的不想锁定处理数据的整个表。
预先感谢您的帮助,
格兰特
贾斯汀 - 感谢您的快速回复,我很欣赏你列出了几个选项的事实! – Grant