批量更新执行流程如何工作
Posted
技术标签:
【中文标题】批量更新执行流程如何工作【英文标题】:how dows bulk update flow of execution works 【发布时间】:2013-09-05 20:38:14 【问题描述】:我正在编写一些代码,这些代码会将数十亿数据从一个表复制到另一个表,并且我们不希望该过程在出现异常时停止。所以我把脚本放在了(不是把 100% 可编译的语法)
dml_errors exception;
errors number;
error_count number;
pragma exception_init (dml_errors, -24381);
---------
open cursor;
begin loop;
fetch cursor bulk collect into tbl_object limit batch_size;
exit when tbl_object.count = 0;
-- perform business logic
begin
forall in tbl_object save exceptions;
insert into table;
tbl_object.delete;
exception
when dml_errors then
errors := sql%bulk_exceptions.count;
error_count := error_count + errors;
insert into log_table (tstamp, line) values (sysdate, SUBSTR('[pr_procedure_name:'||r_guid||'] Batch # '||batch_number - 1||' had '||errors||' errors',1,300));
end;
end loop;
close cursor;
end procedure;
现在基于这个伪代码我有 2 个问题
-
我正在 forall 循环中删除我的收藏。如果出现异常并且我决定从 dml_errors 块中的集合中获取一些信息,我会在其中包含集合元素吗?如果是,那么在登录后删除它们是否安全?
由于我将 forall 保留在 begin-exception-end 块中,它会继续迭代吗?
【问题讨论】:
【参考方案1】:你确定你需要在这里使用 PL/SQL 吗?除非您在业务逻辑中进行大量处理而没有向我们展示在 SQL 中无法完成的处理,否则我倾向于使用DML error logging。这将更高效、更少代码,并为您提供更好的日志记录。
DBMS_ERRLOG.CREATE_ERROR_LOG( 'DESTINATION_TABLE' );
INSERT INTO destingation_table( <<columns>> )
SELECT <<columns>>
FROM source_table
LOG ERRORS
REJECT LIMIT UNLIMITED;
我认为没有任何理由从您的 tbl_object
收藏中删除。这似乎没有给你带来任何好处。这只是花费一些时间。如果您的缩进表示您预期的控制流,那么您认为delete
是forall
循环的一部分——这是不正确的。只有insert
是forall
的一部分,delete
是一个单独的操作。
如果您的第二个问题是“如果在迭代 N 中引发异常,循环是否仍会执行第 N+1 次提取”,答案是肯定的。
有一点需要注意——因为error_count
没有被初始化,所以它总是为NULL。您需要将其初始化为 0 以记录错误总数。
【讨论】:
我在这里使用 pl/sql 有两个原因。 1,src 表在远程数据库中,所以我将使用 dblinks。 2, src 表有数十亿条记录,我必须与本地表进行比较,如果丢失,我必须将其插入单独的表中。所以我想在批处理中做到这一点。 关于error_log_table的问题。在阅读了几个教程后,我注意到我不能使用forall
。我对吗 ?那我该如何使用批量插入器?其次,err_log 功能不记录唯一约束违规(在我的情况下这是最可能的)
@Em Ae - 源表是远程的这一事实似乎无关紧要。您可以使用 SQL 插入目标表中不存在的所有行(或者,如果您确实想要更新本地表,如果源中有匹配的行,则更有可能执行 MERGE
)。如果您使用 DML 错误日志记录,则不会使用 forall
,因为您没有使用 PL/SQL 集合。并且 DML 错误日志记录肯定会记录唯一的约束违规。以上是关于批量更新执行流程如何工作的主要内容,如果未能解决你的问题,请参考以下文章
Android逆向小技巧③:批量注入日志,打印目标程序执行流程
Android逆向小技巧③:批量注入日志,打印目标程序执行流程