他们是否可以记录由于传入参数而发生的错误? 即
PROCEDURE customer_collateral_hist(i_Vcust_cd IN customer_collateral_history.cust_cd%TYPE,
i_Vfromdate IN customer_collateral_history.reg_dttm%TYPE,
i_Vtodate IN customer_collateral_history.reg_dttm%TYPE,
i_Vauthstat IN customer_collateral_history.auth_stat%TYPE,
o_Cresultset OUT SYS_REFCURSOR)
AS
BEGIN
OPEN o_Cresultset FOR
SELECT auth_stat,
buld_size,
clos_dt,
cnfm_dt,
cnfm_tm,
cnfm_user_id,
cust_cd,
date_seq,
dbtr,
dbtr_addr,
dbtr_id,
dbtr_tel_no,
dbtr_zip_cd1,
dbtr_zip_cd2,
esta_orga,
grnt_dt_from,
grnt_dt_to,
jdg_amt,
jdg_dt,
land_size,
loc_addr,
mort_amt,
mort_chng_dt,
mort_flag,
mort_max_amt,
mort_seq,
mort_stat,
old_key,
ownr,
ownr_addr,
ownr_id,
ownr_tel_no,
ownr_zip_cd1,
ownr_zip_cd2,
prev_mort_amt,
redm_dt,
reg_dt,
reg_dttm,
reg_flag,
reg_user_id,
remark,
supr_pow_flag
FROM customer_collateral_history
WHERE cust_cd LIKE '%'||NVL(i_Vcust_cd, cust_cd)||'%'
AND TO_NUMBER(SUBSTR(reg_dttm, 1, 8)) >= NVL(i_Vfromdate, TO_NUMBER(SUBSTR(reg_dttm, 1, 8)))
AND TO_NUMBER(SUBSTR(reg_dttm, 1, 8)) <= NVL(i_Vtodate, TO_NUMBER(SUBSTR(reg_dttm, 1, 8)))
AND auth_stat LIKE '%'||NVL(i_Vauthstat, auth_stat)||'%';
EXCEPTION
WHEN OTHERS THEN
NULL;
END customer_collateral_hist;
END customer;
/
在上面的过程中,我将通过调用此过程来更改异常处理程序
CREATE OR REPLACE procedure
APMS.write_error_log ( errstr varchar2, errline varchar2)
IS
pragma autonomous_transaction;
-- this procedure stays in its own new private transaction
begin
INSERT INTO error_log
(err_tmsp,
err_msg,
err_line_no
)
values (systimestamp,
errstr,
errline
);
COMMIT; -- this commit does not interfere with the caller's transaction.
end write_error_log;
例如,我的write_error_log过程到目前为止,将过程中遇到的错误的时间,消息和行号记录到error_log表中。但是,最后一步是编写一些代码,允许write_error_log过程捕获涉及在参数中调用数据的错误。我希望这是有道理的。
答案 0 :(得分:0)
执行此操作的一种方法是在通过使用ASSERT语句到达时检查参数。 This article显示ASSERT函数。这样的陈述被列为NASA用于safety critical code的一种技术。
只需在每个函数或过程的开头添加一系列断言,以指示您期望的值范围。如果它们在该范围内,则抛出异常,您可以捕获。
答案 1 :(得分:0)
在运行时动态检查调用堆栈中的参数值没有简单的方法。您可能希望将以下一项或两项添加到异常日志
中dbms_utility.format_error_backtrace dbms_utility.format_error_stack
并为其添加另一个参数以允许调用程序发送消息 - 并让每个异常块向您的过程传递输入参数及其值的列表。
所以
PROCEDURE customer_collateral_hist(i_Vcust_cd IN customer_collateral_history.cust_cd%TYPE,
i_Vfromdate IN customer_collateral_history.reg_dttm%TYPE,
i_Vtodate IN customer_collateral_history.reg_dttm%TYPE,
i_Vauthstat IN customer_collateral_history.auth_stat%TYPE,
o_Cresultset OUT SYS_REFCURSOR)
AS
BEGIN
OPEN o_Cresultset FOR
SELECT auth_stat,
buld_size,
clos_dt,
cnfm_dt,
cnfm_tm,
cnfm_user_id,
cust_cd,
date_seq,
dbtr,
dbtr_addr,
dbtr_id,
dbtr_tel_no,
dbtr_zip_cd1,
dbtr_zip_cd2,
esta_orga,
grnt_dt_from,
grnt_dt_to,
jdg_amt,
jdg_dt,
land_size,
loc_addr,
mort_amt,
mort_chng_dt,
mort_flag,
mort_max_amt,
mort_seq,
mort_stat,
old_key,
ownr,
ownr_addr,
ownr_id,
ownr_tel_no,
ownr_zip_cd1,
ownr_zip_cd2,
prev_mort_amt,
redm_dt,
reg_dt,
reg_dttm,
reg_flag,
reg_user_id,
remark,
supr_pow_flag
FROM customer_collateral_history
WHERE cust_cd LIKE '%'||NVL(i_Vcust_cd, cust_cd)||'%'
AND TO_NUMBER(SUBSTR(reg_dttm, 1, 8)) >= NVL(i_Vfromdate, TO_NUMBER(SUBSTR(reg_dttm, 1, 8)))
AND TO_NUMBER(SUBSTR(reg_dttm, 1, 8)) <= NVL(i_Vtodate, TO_NUMBER(SUBSTR(reg_dttm, 1, 8)))
AND auth_stat LIKE '%'||NVL(i_Vauthstat, auth_stat)||'%';
EXCEPTION
WHEN OTHERS THEN
write_error_log(SQLERRM, 'Params i_vcust_cd: '||e_vcustid||' eVfromdate: '||t_vFromDate....);
-- if you want to halt execution then re-raise the error up the stack
RAISE;
END customer_collateral_hist;
然后添加到您的处理程序:
CREATE OR REPLACE procedure
APMS.write_error_log ( errstr varchar2, p_tracetext varchar2)
IS
pragma autonomous_transaction;
-- this procedure stays in its own new private transaction
begin
INSERT INTO error_log
(err_tmsp,
err_msg,
trace_Text
)
values (systimestamp,
errstr,
'BackTrace: '||dbms_utility.format_error_backtrace
||chr(10)||' Stack: '||dbms_utility.format_error_stack
||' details: '||p_tracetext
);
COMMIT; -- this commit does not interfere with the caller's transaction.
end write_error_log;
您需要管理的事情是确保一致的编码实践为您提供所需的细节,如果您将异常提升到调用程序,您将重复调用堆栈的每一步 - 效率不是很高。为了避免这种情况,您需要在堆栈的最低深度记录堆栈和详细信息,并在出路时在堆栈顶部写入一次。不难做到 - 但又需要勤奋的编码实践。
祝你好运!