DBMS Pl / SQL - 输出什么...请解释一下?

时间:2013-07-04 08:09:15

标签: oracle stored-procedures error-handling plsql

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;

2 个答案:

答案 0 :(得分: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. 因为没有发现异常,所以调用块认为被调用的过程成功执行,因此处理干净地终止。这就是为什么不重新引发例外是不好的做法。
  6. 请注意,如果在未启用serveroutput的情况下运行此操作,则输出将为:

    PL/SQL procedure successfully completed.
    
    SQL>
    

答案 1 :(得分:-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;

如果有一行hosid ='H5'收取给定ID的费用,请打印并传递出去。

注意:它仅适用于每个ID一行。如果有多个。将引发TO_MANY_VALUES异常。