如果集合为空,FETCH INTO不会引发异常,是吗?

时间:2011-02-02 23:15:10

标签: oracle exception plsql cursor

以下是我正在尝试调试的一些实际代码:

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)为空时,它会将NULL读取到三个变量中,并且不会抛出异常。

所以无论谁编写这段代码都希望它抛出异常是对的,对吧?注释似乎意味着预期空提取,然后它为以后的处理设置了一个标志,但我认为这个代码也不可能用空集测试。

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

2 个答案:

答案 0 :(得分: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,但尚未执行提取
  • 如果已成功执行提取,则返回TRUE
  • 如果没有返回任何行,则返回FALSE。

答案 1 :(得分: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或类似的。