【问题标题】:FETCH INTO doesn't raise an exception if the set is empty, does it?如果集合为空,FETCH INTO 不会引发异常,是吗?
【发布时间】:2011-06-20 08:18:00
【问题描述】:

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

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 或类似的。

【问题讨论】:

    标签: oracle exception plsql cursor


    【解决方案1】:

    当参数化游标bservice(prod_id)为空时,将NULL取入三个变量,不抛出异常。

    错了

    当 t 为 empty 时,它不获取任何内容,并且不会覆盖任何值。

    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 或类似的。 是的

    【讨论】:

    • Nyffenegger 是的,它基本上就像 SQL Server 一样工作。我认为 FETCH 没有覆盖变量是没有检测到这个错误的原因。不知道为什么首先使用游标,因为您可以选择变量,或者直接进入更新......
    【解决方案2】:

    如果您想知道游标是否返回任何结果,请使用 %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

    %找到
    • 如果游标已声明但未打开,则返回 INVALID_CURSOR;或者如果光标已关闭。
    • 如果游标打开,但未执行 fetch,则返回 NULL
    • 如果执行成功,则返回 TRUE
    • 如果没有返回行,则返回 FALSE。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-18
      • 2020-03-31
      • 1970-01-01
      • 1970-01-01
      • 2019-11-04
      相关资源
      最近更新 更多