7
SELECT Value1 INTO lValue
FROM   Table1
WHERE  Field1 = lTempValue;

一致が真の場合、これは正常に機能します。しかし、一致しない場合は、エラーが発生します。

ORA-01403: no data found

理想的には、それで問題ありません。次にその値をチェックして、0 より大きいかどうかを確認し、0 より大きい場合は、その値を挿入クエリで使用するからです。値を確認したくないので、同じクエリを実行して本質的に取得する必要があります。可能であれば1つのクエリで実行したいのですが、その方法がわかりません。

値がある場合は、その値を lValue に入れます。値がない場合は、lValue に 0 を入れます。誰でもアイデアはありますか?私は簡単なGoogleチェックを行っただけですが、それは乾いていました. 見ながら投稿しようと思いました。助けてくれてありがとう。

4

5 に答える 5

16

通常、例外をキャッチするだけです

BEGIN
  SELECT value1
    INTO lValue
    FROM table1
   WHERE field1 = lTempValue;
EXCEPTION
  WHEN no_data_found
  THEN
    lvalue := 0;
END;

NVLおよび集約関数 (MINまたは)を使用して記述するコードを減らすことができますMAXが、それは少しわかりにくい傾向があります (たとえば、これらの回答は数回修正する必要があることに注意してください)。そして、あなたの後に来る人は、あなたが何をしているのか (そして、あなたがそれを正しく行っているかどうか) を理解するために少し立ち止まる必要があります。単純なネストされた PL/SQL ブロックは非常に一般的で、一目瞭然です。

ただし、それ以上に、行の重複によるバグを隠しません。table1where field1isで2 つの行を取得した場合lTempValue、例外だけをキャッチno_data_foundすると、予期しないことが可能になります。too_many_rows呼び出し元まで伝播する例外。複数の行があるとは思わないので、それはまさにあなたが望む動作です。集計関数を使用すると、基になるデータに問題があり、誤った結果を返す可能性があり、問題があることを検出できなくなるという事実が隠されます。何年も後に何百万もの重複行があることを発見するよりも、何かが重複行を発生させているとすぐにエラーが発生し、手に負えなくなる前に問題を修正できるようにすることを常に望んでいます。コードは時折誤った結果を返すことがあり、根本的な原因に対処した後、膨大な量のデータ クレンジング作業を行っています。

于 2012-08-22T19:53:47.413 に答える
3

Justin Cave の提案に代わる方法として、次のように、常に行を返すようにクエリを少し書き直すことができます。

SELECT NVL(Value1, 0) INTO lValue
FROM   Table1
RIGHT
JOIN   dual
ON     Field1 = lTempValue
于 2012-08-22T20:32:37.487 に答える
2

誰もがこれを本当に複雑にしているようです。値がレコードやクロブのような奇妙なタイプではないと仮定して、これを実行してください。

SELECT NVL(MIN(Value1), 0) INTO lValue
FROM   Table1
WHERE  Field1 = lTempValue;
于 2012-08-24T19:43:17.317 に答える
1

私はカーソルとしてそれを行います-念のために(ストアドプロシージャ内のようにPLSQLブロックを迷わせるという考えは好きではないのでBEGIN ....END;)、次のようになります。

CREATE OR REPLACE .....
...

 CURSOR c_get_val IS
 SELECT Value1 
 FROM   Table1
 WHERE  Field1 = lTempValue;

 lValue    Table1.Value1%TYPE;
 lTempValue  Table1.Table1%TYPE;

その後、

BEGIN
...
....
 /* populate lTempValue */

 OPEN c_get_val;
 FETCH c_get_val INTO lValue;
 if c_get_val%NOTFOUND    --this is where you handle ORA-01403: no data found
 then
   lValue := 0;
   /*or call a function, do some other stuff*/
 end if;
 CLOSE c_get_val; 
...
...
EXCEPTION
  /*do some smart exception handling here*/
END;

カーソルに関するいくつかの情報、およびその他、およびその他

于 2012-08-23T21:23:43.683 に答える
-1
BEGIN
  SELECT value1
    INTO lValue
    FROM table1
   WHERE field1 = lTempValue;
EXCEPTION
  WHEN no_data_found
  THEN
    lvalue := 0;
EXCEPTION
  WHEN too_many_rows
  THEN
    lvalue := 0;
END;
于 2012-08-24T21:04:51.180 に答える