2011-02-02 112 views
2

下面是一些实际的代码我试图调试:如果设置为空,FETCH INTO不会引发异常,是吗?

BEGIN 
      OPEN bservice (coservice.prod_id); 

      FETCH bservice 
      INTO v_billing_alias_id, v_billing_service_uom_id, v_summary_remarks; 

      CLOSE bservice; 

      v_service_found := 1; 
     -- An empty fetch is expected for some services. 
     EXCEPTION 
      WHEN OTHERS THEN 
       v_service_found := 0; 
     END; 

当参数化光标bservice(PROD_ID)是空的,它取空到三个变量,并且不抛出异常。

因此,编写此代码期望它抛出异常的人是错误的,对吧?评论似乎意味着和预计空取回,然后它为稍后处理设置一个标志,但我认为这个代码不可能已经用空集测试过。

显然,它应该使用bservice%NOTFOUND或bservice%FOUND或类似的。

回答

4

当参数化游标bservice(prod_id)为空时,它将NULL提取到三个变量中,并且不会引发异常。

错误

当T ,它取什么,不覆盖任何价值。

declare 

    cursor c(dt in date) is 
    select dummy from dual 
    where dt > sysdate; 

    dummy_ dual.dummy%type; 

begin 

    open c(sysdate + 2); 
    fetch c into dummy_; 
    close c; 
    dbms_output.put_line('1: ' || dummy_); 

    open c(sysdate - 2); 
    fetch c into dummy_; 
    close c; 
    dbms_output.put_line('2: ' || dummy_); 

end; 
/

打印

1: X 
2: X 

所以谁写这段代码期待它抛出一个异常是错误的,对不对?

显然,它应该使用bservice%NOTFOUND或bservice%FOUND或类似的。 是的

+0

Nyffenegger对,它基本上就像SQL Server一样工作。我认为FETCH不覆盖变量就是为什么没有检测到这个错误。不知道为什么光标首先被使用,因为你可以选择变量,或者直接进入更新... – 2011-02-03 15:12:16

4

如果你想知道,如果游标返回任何结果,使用%FOUND光标属性:

 OPEN bservice (coservice.prod_id); 

     FETCH bservice 
     INTO v_billing_alias_id, v_billing_service_uom_id, v_summary_remarks; 

     -- An empty fetch is expected for some services. 
     IF (bservice%FOUND) THEN 
      v_service_found := 1; 
     ELSE 
      v_service_found := 0; 
     END IF 

     CLOSE bservice; 

cursor attributes

%FOUND
  • 返回INVALID_CURSOR如果游标声明,但没开;或者光标已关闭。
  • ,则返回null光标是开放的,但如果取指一个成功提取已被执行
  • 返回FALSE,如果没有返回行尚未执行
  • 返回TRUE。
相关问题