当我传递一个输入参数时,我有一个存储过程。使用该输入参数,如果有no_data_found,那么我提出异常试图在该错误日志表中存储no_data_found错误,但我无法做到。请在下面找到我的代码,
存储过程:
create or replace procedure dumm_proc (p_opportunity_number cct_opportunity.opportunity_number%type)
as
v_oppo_id varchar2(50);
l_message varchar2(50) := sqlerrm;
l_code varchar2(50) := sqlcode;
begin
select opportunity_id into v_oppo_id
from cct_opportunity
where opportunity_number = p_opportunity_number;
exception
when no_data_found then
raise;
xxcct_error_logs(cct_error_seq.nextval,null,v_oppo_id,null,null,l_message,l_code,'dumm_proc',null,sysdate,user,sysdate,user);
when others then
xxcct_error_logs(cct_error_seq.nextval,null,v_oppo_id,null,null,l_message,l_code,'dumm_proc',null,sysdate,user,sysdate,user);
end;
使用其他错误日志过程(xxcct_error_logs)将值存储到表中,但始终存储正常,成功完成。
请建议如何通过调用error_logs过程来存储no_data_found错误。
答案 0 :(得分:0)
from tkinter import *
def intro():
chapterFrame = Frame(root)
chapterFrame.pack()
topFrame = Frame(chapterFrame) # top and bottom frames are children of chapterFrame
topFrame.pack()
photo = PhotoImage(file="hh.gif")
label = Label(topFrame, image=photo)
label.image = photo
label.pack(side=TOP)
t = Text(topFrame, wrap=WORD, height=10)
t.insert(INSERT, "This is the first screen")
t.pack()
bottomFrame = Frame(chapterFrame)
bottomFrame.pack(side=BOTTOM)
# button 1 here should take us to the second screen
# button1 deletes the entire chapter and calls chapter2
button1 = Button(bottomFrame, text="Option 1", fg="black", command=lambda: (chapterFrame.destroy(), chapter2()))
button2 = Button(bottomFrame, text="Option 2", fg="black")
button3 = Button(bottomFrame, text="Option 3", fg="black")
button1.pack(side=LEFT)
button2.pack(side=LEFT)
button3.pack(side=LEFT)
def chapter2():
chapterFrame = Frame(root)
chapterFrame.pack()
topFrame = Frame(chapterFrame)
topFrame.pack()
photo1 = PhotoImage(file="hh2.gif")
label1 = Label(topFrame, image=photo1)
label1.image = photo1
label1.pack(side = TOP)
t1 = Text(topFrame, wrap=WORD)
t1.insert(INSERT, "This is the second screen")
t1.pack()
bottomFrame = Frame(chapterFrame)
bottomFrame.pack(side=BOTTOM)
button4 = Button(bottomFrame, text="this", fg="black")
# button5 loops back to intro
button5 = Button(bottomFrame, text="that", fg="black", command=lambda: (chapterFrame.destroy(), intro()))
button6 = Button(bottomFrame, text="the other", fg="black")
button4.pack(side=LEFT)
button5.pack(side=LEFT)
button6.pack(side=LEFT)
root = Tk()
intro()
root.mainloop()
结束执行并将异常传递回调用者,因此无法访问错误记录器的调用:
raise
作为第一步,我会将其更改为:
exception
when no_data_found then
raise;
xxcct_error_logs(cct_error_seq.nextval, ... );
错误记录器似乎有很多参数。可能它本身可以找出大部分细节,而你需要传递的只是对程序试图失败的描述。
编辑:
我错过了您在错误之前为异常详细信息填充变量。那时没有错误。您需要捕获异常处理程序中的详细信息。你甚至不需要变量。为什么不呢:
exception
when no_data_found then
xxcct_error_logs(cct_error_seq.nextval, ... );
raise;
甚至更简单,根本不要传递它。在xxcct_error_logs
( cct_error_seq.nextval
, null
, v_oppo_id
, null
, null
, sqlerrm -- Just capture sqlerrm here
, sqlcode
, 'dumm_proc'
, null
, sysdate
, user
, sysdate
, user );
程序中,它可以检查是xxcct_error_logs
,如果不是,它可以选择sqlcode = 0
。当你在它的时候,你可以让它照顾sqlerrm
,而不是要求每个来电者知道使用什么序列;对于用户,时间戳等等也是如此。我的日志过程如下所示:
cct_error_seq.nextval
答案 1 :(得分:0)
原因是因为您在异常被提升到默认值之前分配l_message,l_code的值,所以executon始终是正常的。希望这段代码有所帮助。
CREATE OR REPLACE
PROCEDURE dumm_proc(
p_opportunity_number cct_opportunity.opportunity_number%type)
AS
v_oppo_id VARCHAR2(50);
l_message VARCHAR2(50) := sqlerrm;
l_code VARCHAR2(50) := SQLCODE;
BEGIN
SELECT opportunity_id
INTO v_oppo_id
FROM cct_opportunity
WHERE opportunity_number = p_opportunity_number;
EXCEPTION
WHEN no_data_found THEN
-- raise;
l_message:=SQLERRM;
l_code :=SQLCODE;
xxcct_error_logs(cct_error_seq.nextval,NULL,v_oppo_id,NULL,NULL,l_message,l_code,'dumm_proc',NULL,sysdate,USER,sysdate,USER);
WHEN OTHERS THEN
l_message:=SQLERRM;
l_code :=SQLCODE;
xxcct_error_logs(cct_error_seq.nextval,NULL,v_oppo_id,NULL,NULL,l_message,l_code,'dumm_proc',NULL,sysdate,USER,sysdate,USER);
END;
以下代码段以便于理解
SET serveroutput ON;
DECLARE
l_message VARCHAR2(100):=SQLERRM;
l_code VARCHAR2(100):=SQLCODE;
BEGIN
dbms_output.put_line(l_message||'-->'||l_code);
END;
--Now raising exception forcefully
SET serveroutput ON;
DECLARE
l_message VARCHAR2(100):=SQLERRM;
l_code VARCHAR2(100):=SQLCODE;
l_var PLS_INTEGER;
BEGIN
BEGIN
l_var:='abc';
EXCEPTION
WHEN VALUE_ERROR THEN
l_message:=SQLERRM;
l_code :=SQLCODE;
END;
dbms_output.put_line(l_message||'-->'||l_code);
END;