如何修改我的 PL/SQL 过程以进行异常处理?

Posted

技术标签:

【中文标题】如何修改我的 PL/SQL 过程以进行异常处理?【英文标题】:How can I modify my PL/SQL procedure to go to my exception handling? 【发布时间】: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 ;

【问题讨论】:

【参考方案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 有成千上万条错误消息:最好对错误消息不做任何处理,而不是将其丢弃。

【讨论】:

以上是关于如何修改我的 PL/SQL 过程以进行异常处理?的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL数据开发那点事

处理过程 PL/SQL 的异常

PL/SQL 过程和 Toad 执行?

Pl Sql 过程在使用 oracle 调度程序进行调度时处理异常

动态 SQL/异常处理 -00942 - Oracle PL/SQL [重复]

Oracle pl/sql 更新表的过程 - 异常处理