【发布时间】:2014-02-07 20:49:07
【问题描述】:
我在使用 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”语法添加到游标定义中是个好主意,以便在读取数据和删除记录之间,另一个进程无法更新任何记录。
所以,我更改的代码中唯一的事情是……
cursor My_Data_Cur
is
select col1
,col2
from My_Table_1
for update;
当我在此更改后运行 PL/SQL 包时,作业仅处理 100 条记录,然后终止。我通过从游标中删除“for update”确认此更改导致了问题,并且包再次处理了源表中的所有记录。
任何想法为什么添加“for update”子句会导致这种行为变化?有关如何解决此问题的任何建议?我将尝试在流程开始时在表上启动独占事务,但这不是一个理想的解决方案,因为我真的不想锁定处理数据的整个表。
提前感谢您的帮助,
授予
【问题讨论】:
标签: oracle bulk-collect