在使用 BULK COLLECT 处理 Oracle (11g) 中的记录时,我遇到了一个有趣且意外的问题。
以下代码运行良好,处理了所有数百万多条记录而没有出现问题:
-- 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)结束时,我们正在删除刚刚读取和处理的记录,我认为将“for update”语法添加到游标定义中是个好主意,以便另一个进程可以'在读取数据和删除记录之间不更新任何记录。
所以,我更改的代码中唯一的事情是……</p>
cursor My_Data_Cur
is
select col1
,col2
from My_Table_1
for update;
当我在此更改后运行 PL/SQL 包时,作业只处理 100 条记录,然后终止。我通过从游标中删除“for update”确认此更改导致了问题,并且包再次处理了源表中的所有记录。
任何想法为什么添加“for update”子句会导致这种行为变化?有关如何解决此问题的任何建议?我将尝试在流程开始时在表上启动独占事务,但这不是一个理想的解决方案,因为我真的不想锁定处理数据的整个表。
在此先感谢您的帮助,
授予