1

在执行 DML 时,我有 2 个关于 PL/SQL 脚本性能的问题。当然,这EXECUTE IMMEDIATE是最慢的,这就是我们拥有forallbulk插入等的原因。我的问题是

  1. 我必须处理 3 个不同表中的数据。Table1(插入数据)、Table2(更新数据)和Table3删除数据。所有这些都将基于使用游标获取的值来完成。问题是在这里什么会更有效?
    • 将这些语句中的每一个放在单独的Forall块中?IE
fetch cursor
loop
   forall loop for table 1
   forall loop for table 2
   forall loop for table 3
end loop

或者

  • 一个全局循环并在该循环中执行这些语句,即
fetch cursor loop
    for i IN array.count 
    loop
       3 statements for DML
    end loop end loop

现在我的第二个问题

  1. 循环删除记录的有效方法是什么?我通过游标获取要删除的记录的值。现在删除它们的有效方法是什么?

PS:执行我的格式化

4

1 回答 1

4

最有效的方法是编写三个 SQL 语句,假设从游标获取的数据在过程运行的时间段内是稳定的

INSERT INTO table1( list_of_columns )
  <<your SELECT statement>>

UPDATE table2
   SET (<<list of columns>>) = (<<your SELECT statement joined to table2>>)
 WHERE EXISTS( <<your SELECT statement joined to table2>> );

DELETE FROM table3
 WHERE EXISTS( <<your SELECT statement joined to table3>> );

如果该SELECT语句可能会在三个 DML 语句中的每一个中返回不同的结果,那么接受使用游标、将数据批量收集到 PL/SQL 集合中以及遍历集合以确保一致的性能是有意义的结果。如果这就是您正在做的事情,那么拥有三个语句会更有效,FORALL因为这会减少 SQL 和 PL/SQL 引擎之间的上下文转换。

循环删除记录的有效方法是什么?我通过游标获取要删除的记录的值。现在删除它们的有效方法是什么?

我不确定我是否理解这个问题。你不会像对 an或 an那样做一个FORALL循环吗?INSERTUPDATE

FORALL i IN l_array.first .. l_array.last
  DELETE FROM some_table
   WHERE some_key = l_array(i);

或者你在问一个不同的问题?

于 2011-12-01T19:02:59.800 回答