-2

SQL> DESC ホステル;

Name                                      Null?             Type 
    ------------------------------------  --------          ------------------- 
    HOSTELID                              NOT NULL          VARCHAR2(4) 
    ROOMSAVAILABLE                                              NUMBER(3) 
    HOSTELTYPE                                              VARCHAR2(1) 
    HOSTELFEE                                               NUMBER(6) 

sql> select * from hostel;

HOST    ROOMSAVAILABLE      H       HOSTELFEE 
------- ---------------------- ----     --------------------- 
H1              2           M           2000 
H2              3           F           3000

上記の表は、ホステルとその値を示しています。次の pl/sql プログラムの出力はどうなりますか? 詳しく説明してください。

CREATE OR REPLACE PROCEDURE sp_validatehostelid 
(p_hostelid IN hostel.hostelid%TYPE, 
p_hostelfee OUT hostel.hostelfee%TYPE 
) 
IS 
v_count NUMBER; 
v_hostelfee hostel.hostelfee%TYPE; 
BEGIN 
SELECT COUNT(*) INTO v_count FROM hostel WHERE hostelid=p_hostelid; 
IF v_count=0 THEN 
RAISE_APPLICATION_ERROR(-20000,'Invalid Hostel id'); 
ELSE 
SELECT hostelfee INTO v_hostelfee FROM hostel WHERE hostelid=p_hostelid; 
DBMS_OUTPUT.PUT_LINE('Hostel Fee:'||v_hostelfee); 
END IF; 
EXCEPTION 
WHEN NO_DATA_FOUND THEN 
DBMS_OUTPUT.PUT_LINE('No data found'); 
WHEN OTHERS THEN 
DBMS_OUTPUT.PUT_LINE('Other Errors in Procedure'); 
END sp_validatehostelid; 
Procedure created. 

DECLARE 
g_hostelfee hostel.hostelfee%TYPE; 
BEGIN 
sp_validatehostelid('H5',g_hostelfee); 
EXCEPTION 
WHEN OTHERS THEN 
DBMS_OUTPUT.PUT_LINE('Other Errors in Block'); 
END;
4

2 に答える 2

2

「出力はどうなりますか?hostelid = 'H5' を持つ行がない場合」

serveroutput が有効になっているクライアントでこれを実行すると仮定すると、出力は次のようになります。

Other Errors in Procedure
PL/SQL procedure successfully completed.

SQL>

なんで?

  1. 最初の select ステートメントはカウントであり、NO_DATA_FOUND 例外をスローすることはできません。
  2. 次の行では、ユーザー定義の例外 -20000 が発生します。
  3. これにより、制御が例外ハンドラ ブロックに渡されます。-20000 は NO_DATA_FOUND ではないため、WHEN OTHERS 句が実行され、上記のメッセージが表示されます。
  4. 例外ハンドラー自体は例外を発生させません。これは非常に悪い習慣です。したがって、フローは呼び出しブロックに戻ります。
  5. 例外が見つからなかったため、呼び出しブロックは呼び出されたプロシージャが正常に実行されたと見なし、処理は正常に終了します。そのため、例外を再発生させないのは悪い習慣です。

最初に serveroutput を有効にせずにこれを実行すると、出力は次のようになることに注意してください。

PL/SQL procedure successfully completed.

SQL>
于 2013-07-04T14:04:42.620 に答える
-1
CREATE OR REPLACE PROCEDURE sp_validatehostelid 
(
    p_hostelid IN hostel.hostelid%TYPE, 
    p_hostelfee OUT hostel.hostelfee%TYPE 
) 
IS 
    v_count NUMBER; 
    v_hostelfee hostel.hostelfee%TYPE; 
BEGIN 
    /* Count rows in 'hostel' table for given ID */
    SELECT COUNT(*) INTO v_count FROM hostel WHERE hostelid=p_hostelid; 
    /* If there is noting in the table */
    IF v_count=0 THEN 
        /* raise exception */
        RAISE_APPLICATION_ERROR(-20000,'Invalid Hostel id'); 
    ELSE
        /* select fee from the 'hostel' table */
        SELECT hostelfee INTO v_hostelfee FROM hostel WHERE hostelid=p_hostelid; 
        /* print the fee */
        DBMS_OUTPUT.PUT_LINE('Hostel Fee:'||v_hostelfee); 
    END IF; 
EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
        DBMS_OUTPUT.PUT_LINE('No data found'); 
    WHEN OTHERS THEN 
        DBMS_OUTPUT.PUT_LINE('Other Errors in Procedure'); 
END sp_validatehostelid; 


DECLARE 
    g_hostelfee hostel.hostelfee%TYPE; 
BEGIN 
    sp_validatehostelid('H5',g_hostelfee); 

    /* 
    **Here something should be done with 'g_hostelfee' variable
    */
EXCEPTION 
    WHEN OTHERS THEN 
        DBMS_OUTPUT.PUT_LINE('Other Errors in Block'); 
END;

Hostelid = 'H5' の行がある場合は、指定された ID の料金を徴収し、それを印刷して渡します。

注: ID ごとに 1 つの行に対してのみ機能します。複数ある場合。TO_MANY_VALUES 例外が発生します。

于 2013-07-04T08:21:21.633 に答える