19

SELECT INTOステートメントが少なくとも1つの行を返さない場合、ORA-01403がスローされます。

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

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ブロック全体を記述する必要があります。

見えない本質的な理由はありますか?

4

7 に答える 7

22

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

ここでは、例外を積極的に無視しています (プロシージャは正常に返されます) が、ほとんどの場合、SELECT INTO を実行している場合、行が返されない場合は失敗させたいと考えています。

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;

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

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

于 2010-10-15T08:36:13.637 に答える
12

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

これは見落とされがちな一般的な状況であるため、これが行われたと思います。常にデータが見つかることを期待しているかのようにコードを書くことはよくあることです。

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

SQLCODE = 100 のチェックが頻繁にスキップされる可能性があります。例外が発生すると、A) 重要な状態 (データが見つからない) が発生し、B) これには許可が与えられていないことがわかります。PL/SQLエンジンに例外を発生させるIMOは、実際にはデータが取得されなかったときにデータが取得されたという仮定の下で、プログラムを楽しく続行させるよりも優れています。

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

于 2010-10-15T12:13:07.993 に答える
7

EXCEPTION句を使用しないように、MINを使用してみてください。

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

その場合、ダミー変数はNULLになります

于 2010-10-15T08:16:29.270 に答える
4

正確に1行を必要とするSELECTINTOを実行しているためです(行が増えるとエラーにもなります)。

行を1つにすることも、行を持たないこともできる場合は、カーソルを使用できます。

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

于 2010-10-15T08:16:11.343 に答える
2

SQL のMAX関数またはMIN関数を使用することもできます。行が返されない場合、これらの関数はNULLを返します。

例: Select MAX (column1) Into variable From Table Where Column1 = 'Value';

MAX関数は最大値を返すか、行が返されない場合は NULL を返します。

于 2015-11-18T15:26:18.843 に答える
1

PL/SQLエンジンが何をすべきかが明確でないため、ブロックを終了する必要がありますか? 変数に NULL を指定して続行する必要がありますか? 次のブロックでそれを NOT NULL 列に挿入しようとした場合、エラーの場所をどのように報告する必要がありますか? それを例外にすることは、それについて明確にすることを強制します。

于 2010-10-16T17:02:22.157 に答える