10

なぜこのコードが機能しないのか不思議です。id=1テーブルにサプライヤーがありません。

DECLARE
    VAR SUPP_NM VARCHAR(100);
    VAR_SUPP_ID  NUMBER := 1;
    WHILE_VAR CHAR := 'Y';
BEGIN
    SELECT SUPP_NM
    INTO VAR_SUPP_NM
    FROM TEST.SUPPLIER
    WHERE SUPP_ID = VAR_SUPP_ID;
        
    IF SQL%NOTFOUND THEN
        DBMS_OUTPUT.PUT_LINE('SQL DATA NOT FOUND');
    ELSIF SQL%FOUND THEN
        DBMS_OUTPUT.PUT_LINE('DATA FOUND');
    END IF;    
END;

Toad で 01403 エラーが発生しますが、として処理されませんsql%notfound

なぜ機能しないのsql%notfoundですか?

4

3 に答える 3

19

例外をキャッチするには、セクションNO_DATA_FOUNDを追加して次のようにコードを書き直します。exception

DECLARE
    VAR_SUPP_NM VARCHAR2(100);
    VAR_SUPP_ID  NUMBER := 1;
    WHILE_VAR CHAR := 'Y';
BEGIN
  SELECT SUPP_NM
    INTO VAR_SUPP_NM
    FROM TEST.SUPPLIER
   WHERE SUPP_ID = VAR_SUPP_ID;

 DBMS_OUTPUT.PUT_LINE('DATA FOUND');

exception
  when no_data_found 
  then DBMS_OUTPUT.PUT_LINE('SQL DATA NOT FOUND');

END;

selectステートメントが行を返さない場合は常に例外が発生するため、ステートメントの場合はチェックSQL%FOUNDするかSQL%NOTFOUND意味がありません。ただし、そのselectステートメントが集計関数を呼び出す場合は常にデータを返すか、行が選択されていない場合はnullを返します。select intono_data_found

varcharデータ型を使用せず、varchar2代わりにデータ型を使用してください。

于 2012-10-25T19:19:16.403 に答える
7

ニコラスの答えは、あなたが使いたいならあなたが望むものですSELECT INTO%FOUNDただし、 orを使用できることがより重要な場合は、代わりにカーソルからの ing を%NOTFOUND検討してください。FETCH

DECLARE
    VAR SUPP_NM VARCHAR2(100);
    VAR_SUPP_ID  NUMBER := 1;
    WHILE_VAR CHAR := 'Y';
    CURSOR c1 IS
        SELECT SUPP_NM
        FROM TEST.SUPPLIER
        WHERE SUPP_ID = VAR_SUPP_ID;
BEGIN
    OPEN c1;
    FETCH c1 INTO VAR_SUPP_NM;

    IF c1%NOTFOUND THEN
            DBMS_OUTPUT.PUT_LINE('SQL DATA NOT FOUND');
    ELSIF c1%FOUND THEN
            DBMS_OUTPUT.PUT_LINE('DATA FOUND');
    END IF;

    CLOSE c1;
END;
于 2015-09-18T19:32:27.740 に答える