2011-11-10 10 views
0

私は、次のを持っている...Oracle例外処理 - これは正しいですか?

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文の例外を処理する正しい方法は何ですか?

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; 

代替が明示的に使用することです:あなたが特定のエラーを無視したい部分の周りのブロックを作成する必要がありますので、

答えて

3

PL/SQLは、エラーの場所に戻す方法はありませんそれが空の場合、エラーを返しません、カーソル、:

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; 
+0

さらに、pl.sqlで空のエラーハンドラを実行する方法については、1を参照してください。 –

3

は、あなたが「正しい」によって何を意味するかによって異なります。あなたが提示したものは、構文的に有効です。はい。しかし、実際に何が起こりたいのかを教えてくれていないので、投稿したコードが実際にあなたが望むことをするかどうかは分かりません。

ビジネスロジックの観点からは、SELECT INTOが0行を返す場合は、実際にはエラーではないと確信していますか?あなたが例外を捕まえて飲み込んでいる場合、それは実際にはエラーではないことを知っていることを意味します。ただし、SELECT INTOをコーディングしている場合は、正確に1つの行が必要であることを意味します。これらのステートメントの両方が真実である可能性は確かですが、実際には例外であり、単純に飲み込んで無視するべきではないということがより一般的になります。

一般に、可能な限り例外をスローする可能性のあるクエリにできるだけ近い例外ハンドラを配置することをお勧めします。私はあなたが、例外が予想されると予想外であるNO_DATA_FOUND例外が、それは明らかであろうスローされる可能性がありますあなたの手順の複数の場所で終わる場合、それはクリーナー、そのように

IF condition1 
THEN 
    BEGIN 
    <<select statement>> 
    EXCEPTION 
    WHEN no_data_found 
    THEN 
     <<do something>> 
    END; 

    IF condition2 
    THEN 
    ... 
    END IF; 
END IF; 

のようなものを持って見つけるだろう。

IFステートメントのネストされたレイヤーが3つあるという点に着目すると、コードを複数の手順にリファクタリングしてコードを明確にしたいと思う傾向があります。たとえば、SELECT文を実行し、例外をキャッチして例外を処理するネストされたPL/SQLブロックを持つのではなく、そのすべてを行った別の関数を持つことが明らかになり、トリガーからその関数を呼び出します。

+0

OPのコードをもう一度見てください。その 'return'は確かに動作しません... – Allan

+0

@Allan - なぜでしょうか?これは構文上、例外ハンドラ内のPL/SQLブロックから戻るために有効です。それは正しい動作ではないかもしれませんが、有効な構文です SQL> create table t(col1 number); テーブルが作成されました。 SQL> create trg_t 2に挿入する前に、 3行ごとに 4 declare 5 l_emp_rec emp%rowtype; 6 begin 7 select * 8 into l_emp_rec 9 from emp 10 empno =:new.col1; 11例外 12 no_data_foundの場合 13 then 14 return; 15 end; 16/ トリガーが作成されました。 SQL> t values(1)に挿入します。 1行が作成されました。 –

+0

あなたは正しいです(もちろん)。私はそのコマンド(機能の外)を全く知らなかった。私はまだ、その行動がOPの期待どおりではないと思う。それはエラーの場所からの実行の再開だと思う。 – Allan