Oracle异常处理 - 这是正确的吗?

时间:2011-11-10 15:02:57

标签: oracle error-handling plsql oracle10g oracle11g

我有以下......

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语句的异常的正确方法吗?

2 个答案:

答案 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块,捕获异常并处理异常,可能更清楚的是有一个单独的函数完成所有操作,然后从触发器调用该函数。