我有以下......
IF CONDITION1 THEN
-- SELECT STATEMENT MIGHT RETURN DATA
IF CONDITION2 THEN
-- SELECT COUNT
IF CONDITION3 THEN
INSERT INTO TABLE
(
---
)
VALUES (
---
);
End IF;
END IF;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN;
END of Trigger
这是处理CONDITION1中的select语句的异常的正确方法吗?
答案 0 :(得分:3)
PL / SQL无法返回错误的站点,因此您需要在要忽略特定错误的部分周围创建一个块:
IF CONDITION1 THEN
BEGIN
-- SELECT STATEMENT MIGHT RETURN DATA
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
END;
IF CONDITION2 THEN
-- SELECT COUNT
IF CONDITION3 THEN
INSERT INTO TABLE
(
---
)
VALUES (
---
);
End IF;
END IF;
END IF;
END TRIGGER_NAME;
另一种方法是使用显式游标,当它为空时不会返回错误:
DECLARE
CURSOR cur_sample is select dummy from dual where 1=0;
v_dummy dual.dummy%type;
BEGIN
IF CONDITION1 THEN
open cur_sample;
fetch cur_sample into v_dummy;
close cur_sample;
IF CONDITION2 THEN
-- SELECT COUNT
IF CONDITION3 THEN
INSERT INTO TABLE
(
---
)
VALUES (
---
);
End IF;
END IF;
END IF;
END;
答案 1 :(得分:3)
取决于“正确”的意思。你所呈现的是语法上有效的,是的。但是你没有告诉我们你真正想要发生什么,所以我们无法告诉你你发布的代码是否真的能够做你想要的。
从业务逻辑的角度来看,如果SELECT INTO返回0行,您确定它确实不是错误吗?如果您正在捕捉并吞下异常,那意味着您知道这不是一个真正的错误。但是,如果您正在编写SELECT INTO,则意味着您只需要一行。这两个陈述当然是正确的,但它更为常见的是它确实是一个例外,它不应该被简单地吞噬和忽略。
一般情况下,我宁愿将异常处理程序尽可能地放在可能引发异常的查询中。有点像
这样的东西我觉得更干净IF condition1
THEN
BEGIN
<<select statement>>
EXCEPTION
WHEN no_data_found
THEN
<<do something>>
END;
IF condition2
THEN
...
END IF;
END IF;
这样,如果你的程序中有多个地方可能会抛出NO_DATA_FOUND异常,那么很明显会出现哪些异常,哪些是意外的。
当你到达三层嵌套的IF语句时,我倾向于怀疑你想要将代码重构为多个过程以使代码更清晰。例如,不是拥有执行SELECT语句的嵌套PL / SQL块,捕获异常并处理异常,可能更清楚的是有一个单独的函数完成所有操作,然后从触发器调用该函数。