web-dev-qa-db-ja.com

Oracleでno_data_found ORA-01403が例外になるのはなぜですか?

SELECT INTO文が少なくとも1行を返さない場合、ORA-01403がスローされます。

他のすべてのDBMSについては、SELECTでこれが正常であることを知っています。 OracleだけがSELECT INTOをこのように扱います。

CREATE OR REPLACE PROCEDURE no_data_proc IS
   dummy dual.dummy%TYPE;
BEGIN
  BEGIN 
     SELECT dummy  
       INTO dummy
       FROM dual
      WHERE dummy = 'Y';   
  EXCEPTION 
     WHEN no_data_found THEN
        dbms_output.put_line('Why is this needed?');
  END;
END no_data_proc;

なぜ?

私の意見では、この例外は本当に必要ありません。オーバーヘッドが大きすぎます。便利な場合もありますが、BEGIN、EXCEPTION、WHEN、END Block全体を記述する必要があります。

表示されない本質的な理由はありますか?

18

例外ブロックはneededではありません。コンテキストに応じて、使用する場合も使用しない場合もあります。

ここでは、例外を積極的に無視しています(プロシージャは正常に戻ります)が、ほとんどの場合、SELECT INTOを実行する場合はfailを返します。

PROCEDURE update_employee_salary (p_empno) IS
   l_salary NUMBER;
BEGIN
   SELECT sal INTO l_salary FROM emp WHERE empno = p_empno FOR UPDATE;
   /* do something with emp data */
END;

ここでは、EMPテーブルに存在しないempnoを指定して呼び出された場合、関数が失敗するようにします。例外をキャッチして、意味のあるエラーメッセージ(raise_application_error)ほとんどの場合、私はORA-01403に満足しています。

一般に、キャッチする必要がある唯一の例外は、予期される例外です(つまり、これはすべてのORA-01403、またはその問題のすべての例外をキャッチするための標準ではありません)。

19
Vincent Malgrat

ただし、「SELECTに取得するデータがない場合になぜ例外がスローされるのか」という質問に答える必要があります。

これは、見過ごされる可能性のある一般的な状況だからです。データを見つけることを常に期待しているようにコードを書くことはよくあることです。

SELECT <something...>
IF SQLCODE = 100 THEN -- No data found
  <no-data handler>
END IF

sQLCODE = 100のチェックが頻繁にスキップされる可能性があります。例外が発生すると、A)重要な状態(データが見つかりません)が発生したこと、およびB)このために許可が得られなかったことを鼻の上で突き上げます。 PL/SQLエンジンに例外を発生させるIMOは、実際にはデータが取得されなかったにもかかわらず取得されたという仮定の下でプログラムを楽に続行させるよりも優れており、これはあらゆる種類の陽気な以外の問題につながる可能性があります。

共有してお楽しみください。

12
Bob Jarvis

EXCEPTION句の使用を避けるには、MINを使用してみてください。

 SELECT MIN(dummy)  
   INTO dummy
   FROM dual
  WHERE dummy = 'Y'; 

ダミー変数はNULLになります

7

正確に1つの行を必要とするSELECT INTOを実行しているためです(複数の行もエラーになります)。

行を1つ持つか、まったく持たない場合は、カーソルを使用できます。

行の欠落がエラーではないと判断し、値をnullに設定するのはデータベースの仕事ではありません。

3
Thilo

Sql [〜#〜] max [〜#〜]または[〜#〜] min [〜#〜]関数も使用できます。行が返されない場合、これらの関数は[〜#〜] null [〜#〜]を返します。

例:Select [〜#〜] max [〜#〜](column1)Into variable From Table Where1 = 'Value';

[〜#〜] max [〜#〜]関数は最大値を返すか、行が返されない場合はNULLを返します。

2
Immortal Code

PL/SQLエンジンが何をすべきかが明確ではないため、ブロックを終了する必要がありますか?変数にNULLを押してオンにする必要がありますか?次のブロックでそれをNOT NULL列に挿入しようとした場合、エラーの場所をどのように報告する必要がありますか?それを例外にすると、明示的にそれを明示しなければなりません。

1
Gaius

MAX関数が機能し、エラーをスローしませんORA-01403select INTOによってNULLが返された場合に機能

1
Gaurav londhe