之前在存储过程中对于insert大量属于可能带来的错误,我一般使用exception异常处理来记录异常并保证程序正确执行,类似于下面这段异常处理代码
declare
--异常信息
startTime timestamp(6); --开始时间
endTime timestamp(6); --结束时间
FERRORCODE VARCHAR(50); --错误代码
FERRORDSC VARCHAR(200); --错误描述
FEXCPCATCHTIME TIMESTAMP(6); --异常抛出时间
v_create_user number := 86301;
procedure t_ps_exception is
begin
startTime := sysdate;
endTime := sysdate;
FERRORCODE := SQLCODE;
FERRORDSC := SQLERRM || dbms_utility.format_error_backtrace();
FEXCPCATCHTIME := sysdate;
insert into DPCRM.t_cust_visMarketingLog--异常插入异常记录表
(FBEGINTIME, FENDTIME, FERRORCODE, FERRORDSC, FEXCPCATCHTIME)
values
(startTime, endTime, FERRORCODE, FERRORDSC, FEXCPCATCHTIME);
commit;
--RAISE;--无法解决的异常抛出
end;
以上代码可以捕获任何oracle预定义的异常和自定义异常。但是需要创建单独的异常表还有代码比较复杂,在简单的插入操作中显得大材小用,今天无意间看到了oracle10gr2之后推出了一个炫酷的功能DML错误日志。这下子让我眼前一亮,我似乎看到了一条简单有效的方法来记录dml异常了。
应用场景:
如果在一个事务内向一个表中插入一百万条记录,如果其中有一条失败就意味着一百万都要回滚
例如:
1.创建测试表create table dml_log(fid number(5));
2.向表中插入数据insert into dml_log select fid from t_auth_function
t_auth_function表fid字段值如图所示,
3.使用该语句想测试表里面插入数据,理论上138条满足条件,第139条将失败。insert into dml_log select fid from t_auth_function where rownum < 140
如果不实用容错处理,那么结果是一条都不成功。
4.使用dml错误日志记录错误,达到满足条件正常插入,不满足的异常数据被记录。
a.调用过程为指定表创建错误信息记录表。
exec dbms_errlog.create_error_log('dml_log','dml_log_error');
错误日志记录表的结构我就不看了,回头自己看。
5.为insert语句加上错误日志记录功能和容错处理。再看看
138行成功,那么看看错误日志表,
太人性了有木有。以后给自己存在批量dml操作的语句都加上错误日志吧