例外NO_DATA_FOUND没有设置变量值,DBMS_OUTOUT.PUT_LINE没有显示它应该显示

时间:2014-07-04 07:00:59

标签: oracle plsql

我正在尝试执行的简单过程中有这种奇怪的行为。该过程只检查表中是否存在某条记录,如果该记录存​​在,则运行一个过程,如果不存在,则运行另一个过程。程序如下:

PROCEDURE p_checksomething (i_var1 VARCHAR2, 
                            i_var2 VARCHAR2, 
                            i_var3 VARCHAR2, 
                            i_var4 VARCHAR2, 
                            i_var5 VARCHAR2, 
                            i_var6 VARCHAR2, 
                            i_var7 VARCHAR2, 
                            i_var8 VARCHAR2 
                ) 
IS 

v_var1 VARCHAR2(100); 
v_var2 VARCHAR2(100);  
v_var3 VARCHAR2(100);  
v_var4 VARCHAR2(100);  
v_var5 VARCHAR2(100); 
v_flag NUMBER := 0; 

BEGIN 

  dbms_output.put_line('Flag value1: '||v_flag); 


  SELECT a.col1, a.col2, a.col3, a.col4, a.col5 
  INTO v_var1, v_var2, v_var3, v_var4, v_var5  
  FROM table1 a 
  WHERE a.col1 = 'i_var1' 
  AND a.col2 = 'i_var2' 
  AND a.col3 = 'i_var3' 
  AND a.col4 = 'i_var4' 
  AND a.col5 = 'i_var5'; 

  dbms_output.put_line('Flag value2: '||v_flag); 

  EXCEPTION 
  WHEN NO_DATA_FOUND THEN 
   v_flag := 1; 
  WHEN OTHERS THEN RAISE; 

  dbms_output.put_line('Flag value3: '||v_flag); 

IF v_flag = 1 THEN              /*INSERT INTO RU_INFO_T*/ 

 dbms_output.put_line('Flag value4: '||v_flag); 

package1.p_proc010(i_var1,i_var2,i_var3,i_var4,i_var5,i_var6,i_var7,i_var8); 

ELSE    IF v_flag = 0 THEN          /*UPDATE INTO RU_INFO_T*/ 

 dbms_output.put_line('Flag value5: '||v_flag); 
package1.p_proc100(i_var1,i_var2,i_var3,i_var4,i_var5,i_var6,i_var7,i_var8); 
END IF; 

END IF; 
dbms_output.put_line('Flag value6: '||v_insflag); 
END;

虽然它正在正确编译但是当我运行它时,其他两个程序没有运行,而在控制台上我只能看到

Flag value1: 0

其他dbms_output.put_line命令发生了什么,以及为什么变量在没有找到数据的情况下不会发生变化是我要死的事情。如果有人可以思考并告诉我应该做些什么来改变我想要的标志值,这将是非常棒的。

2 个答案:

答案 0 :(得分:3)

您应该尝试添加开始结束块以处理异常。 你只有一个EXCEPTION处理程序 - 它是程序的处理程序。 当你捕获异常时,是的,你初始化v_flag:= 1,然后退出程序;

PROCEDURE p_checksomething (i_var1 VARCHAR2, 
                            i_var2 VARCHAR2, 
                            i_var3 VARCHAR2, 
                            i_var4 VARCHAR2, 
                            i_var5 VARCHAR2, 
                            i_var6 VARCHAR2, 
                            i_var7 VARCHAR2, 
                            i_var8 VARCHAR2 
                ) 
IS 

v_var1 VARCHAR2(100); 
v_var2 VARCHAR2(100);  
v_var3 VARCHAR2(100);  
v_var4 VARCHAR2(100);  
v_var5 VARCHAR2(100); 
v_flag NUMBER := 0; 

BEGIN 

  dbms_output.put_line('Flag value1: '||v_flag); 

BEGIN   ---------------     new line  
  SELECT a.col1, a.col2, a.col3, a.col4, a.col5 
  INTO v_var1, v_var2, v_var3, v_var4, v_var5  
  FROM table1 a 
  WHERE a.col1 = 'i_var1' 
  AND a.col2 = 'i_var2' 
  AND a.col3 = 'i_var3' 
  AND a.col4 = 'i_var4' 
  AND a.col5 = 'i_var5'; 

  dbms_output.put_line('Flag value2: '||v_flag); 

  EXCEPTION 
  WHEN NO_DATA_FOUND THEN 
   v_flag := 1; 
  WHEN OTHERS THEN RAISE; 
END;---------------           new line 

  dbms_output.put_line('Flag value3: '||v_flag); 

IF v_flag = 1 THEN              /*INSERT INTO RU_INFO_T*/ 

 dbms_output.put_line('Flag value4: '||v_flag); 

package1.p_proc010(i_var1,i_var2,i_var3,i_var4,i_var5,i_var6,i_var7,i_var8); 

ELSE    IF v_flag = 0 THEN          /*UPDATE INTO RU_INFO_T*/ 

 dbms_output.put_line('Flag value5: '||v_flag); 
package1.p_proc100(i_var1,i_var2,i_var3,i_var4,i_var5,i_var6,i_var7,i_var8); 
END IF; 

END IF; 
dbms_output.put_line('Flag value6: '||v_insflag); 
END;

答案 1 :(得分:1)

问题是WHEN OTHERS THEN RAISE;之后的所有内容仍然是WHEN OTHERS异常处理程序的一部分。但它是无法访问的代码。

如果您希望在代码中间有一个异常处理程序,则需要一个嵌套的PL / SQL块(BEGINEXCEPTIONEND )。

BEGIN 

  dbms_output.put_line('Flag value1: '||v_flag); 

  BEGIN
    SELECT a.col1, a.col2, a.col3, a.col4, a.col5 
    INTO v_var1, v_var2, v_var3, v_var4, v_var5  
    FROM table1 a 
    WHERE a.col1 = 'i_var1' 
    AND a.col2 = 'i_var2' 
    AND a.col3 = 'i_var3' 
    AND a.col4 = 'i_var4' 
    AND a.col5 = 'i_var5'; 

    dbms_output.put_line('Flag value2: '||v_flag); 

  EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
     v_flag := 1; 
    WHEN OTHERS THEN RAISE; 
  END;

  dbms_output.put_line('Flag value3: '||v_flag); 

当然,只有重新引发异常的WHEN OTHERS异常处理程序才没有意义。最好的情况是你丢弃了错误来自的实际行。应该删除WHEN OTHERS - 只是让异常传播。

根据Oracle版本的不同,compiling with warnings会发出警告,指出RAISE之后的所有内容都无法访问。这可能会指出你解决问题的方向。