我有一个与pl / sql相关的问题。 假设我有一个很长的程序,它有一些INSERTS,SELECTS和所有。
有没有办法当其中一个选项出错时我会确切地知道哪一个?
假设我有
PROCEDURE processRequests IS
P_ID numer;
P_NAME varchar2(20);
BEGIN
SELECT NAME into P_NAME FROM users WHERE ID=P_ID;
SELECT NAME into P_NAME FROM users WHERE ID2=P_ID;
INSERT INTO users (ID,ID2,NAME)values(1,2,'Joe');
END;
我想知道第一个和第二个选择何时返回错误并在错误日志表中更新它,还有一些如果有外键如主键,主键,我希望能够捕获这些错误
我尝试过使用not_found异常,但后来我无法知道错误的位置。
任何提示?
最诚挚的问候 史蒂芬詹姆斯
答案 0 :(得分:1)
您必须使用BEGIN END
块包装每个查询并处理EXCEPTION WHEN
块中的错误。对于select语句,当您想要阻止唯一约束vialotions时,可以使用NO_DATA_FOUND
和DUP_VAL_ON_INDEX
因此代码的结构或多或少会如下所示:
BEGIN
--...
BEGIN
SELECT NAME into P_NAME FROM users WHERE ID=P_ID;
EXCEPTION WHEN NO_DATA_FOUND THEN
-- handle error
END;
BEGIN
INSERT INTO users (ID,ID2,NAME) values(1,2,'Joe');
EXCEPTION WHEN DUP_VAL_ON_INDEX THEN
-- handle error
END;
--...
END;
答案 1 :(得分:1)
要添加到mkuligowski的答案,如果你有一个非常长的块并且你总是想在异常后退出,那么轻量级替代方法是使用一个节标记来确定发生异常的位置。
PROCEDURE processRequests IS
P_ID numer;
P_NAME varchar2(20);
P_SECTION varchar2(30);
BEGIN
P_SECTION := 'first select';
SELECT NAME into P_NAME FROM users WHERE ID=P_ID;
P_SECTION := 'second select';
SELECT NAME into P_NAME FROM users WHERE ID2=P_ID;
P_SECTION := 'first insert';
INSERT INTO users (ID,ID2,NAME)values(1,2,'Joe');
EXCEPTION WHEN OTHERS THEN
dbms_output.put_line('Error in section: ' || p_section);
dbms_output.put_line(dbms_utility.format_error_backtrace);
raise;
END;