【问题标题】:How can I modify my PL/SQL procedure to go to my exception handling?如何修改我的 PL/SQL 过程以进行异常处理?
【发布时间】:2015-05-31 02:27:55
【问题描述】:

我正在使用 SQL 开发人员编写一个过程。

目标是从一张表中获取排水系统的名称,并计算排水系统名称代码在另一张表中出现的次数。

我的程序有效,但是当我输入错误的值时,它不会进入异常部分。例如,当我输入“Mexico River”时,表中不存在此名称。所以,我希望我的异常部分意识到这是一个不正确的输入值。

我的问题是如何修改我的代码,以便它可以检测到不正确的值并转到我的异常部分。

下面是我的代码的 sn-p:

PROCEDURE number_of_rivers --second procedure with 1 parameter
  (input_sysName IN TBLDrainage.DRAINAGE_SYS%TYPE)
   is 

    -- Create a cursor 
    cursor c_river is 
      select code, drainage_sys 
      from TBLDRAINAGE 
      where DRAINAGE_SYS = input_sysName;
    v_rivercount Number;
    r_variable c_river %rowtype; 

  Begin

   FOR r_variable in c_river
   loop 
     select count (Drainage_sys) into v_rivercount
     from TBLRIVER
     where DRAINAGE_SYS = r_variable.code;
     DBMS_OUTPUT.PUT_LINE (UPPER(input_sysName) || ' has ' || v_rivercount || ' river(s) in the drainage system.');
  end loop;


EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE ('Error: Please enter a valid drainage system name');
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE ('Error in finding system');
END ;

【问题讨论】:

    标签: oracle plsql exception-handling


    【解决方案1】:

    CURSOR..FOR 循环具有执行零次或多次的特性。它不会抛出 NO_DATA_FOUND。

    有几个解决方案。一种是在循环中包含一个计数,然后引发异常。

    l_count := 0;
    FOR r_variable in c_river
    loop 
      ....
      l_count := l_count + 1;
    end loop;
    if l_count = 0 then
      raise NO_DATA_FOUND;
    end if;
    

    另一个是在程序开始时验证输入参数。

    begin
      open c_river;
      fetch c_river into r_variable;
      if c_river%notfound then  
        raise NO_DATA_FOUND;
      else
        select count (Drainage_sys) 
        into v_rivercount
        from TBLRIVER
        where DRAINAGE_SYS = r_variable.code;
        DBMS_OUTPUT.PUT_LINE (UPPER(input_sysName) || ' has ' || v_rivercount || ' river(s) in the drainage system.');
      end if;
      close c_river;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        DBMS_OUTPUT.PUT_LINE ('Error: Please enter a valid drainage system name');
        close c_river;
    END ;      
    

    在这个解决方案中,我删除了循环,因为我希望对排水系统的查找应该是唯一的并返回一条记录。如果您的数据模型不是这样,请重新设置循环。


    我保留了游标及其行变量的名称,但您应该重新命名它们。它们用于选择排水系统而不是河流,它们的名称应该反映这一点。命名事物的纪律是一个很有用的习惯,因为误导性的变量名称会在更大的代码块中造成混淆。

    此外,吞下这样的异常是非常糟糕的:

     WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE ('Error in finding system');
    

    Oracle 有成千上万条错误消息:最好对错误消息不做任何处理,而不是将其丢弃。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-10
      • 1970-01-01
      • 1970-01-01
      • 2015-04-04
      • 2016-01-26
      • 1970-01-01
      相关资源
      最近更新 更多