【问题标题】:No data found error in oracle stored procedureoracle存储过程中找不到数据错误
【发布时间】:2014-07-17 04:51:16
【问题描述】:

请在下面找到我写的存储过程:

create or replace

procedure CursorProc_test_vp

(

  v_Cur IN OUT types.ref_cursor,

  count_var IN OUT number,

  var1 IN OUT varchar2,

  var2 IN OUT number,

  var3 IN  OUT number

)

as

begin

  select count(*) into count_var from vendor_backup;

  open v_Cur for 'select column1,column2 from BACKUP where column1 is not null and column2 is null';

    while count_var>0

    loop

      fetch v_Cur into var1,var2;

          SELECT ID into variable3 from BACKUP where column3 = var1;

          UPDATE BACKUP SET column2 = var3;

        count_var:=count_var-1;

      end loop;

  close v_cur;

end;

当我运行打开游标的查询时,我得到 120 条记录。 但是当我运行这个存储过程时,它会显示“未找到数据”。

它也没有编译错误。 我在这里遗漏了什么吗?

【问题讨论】:

  • 您不会从光标本身获得 ORA-01403。如果它没有找到任何行就不会出错,所以错误来自循环内的select

标签: oracle stored-procedures


【解决方案1】:

在不知道您传递什么数据以及表中包含什么数据的情况下尝试将上下文置于过程后面是非常困难的。

我会导致您的 NO_DATA_FOUND 异常的唯一其他 SQL 是:

"SELECT ID into variable3 from BACKUP where column3 = var1;"

在您的过程中用 Begin Exception End Clause 括起来并尝试调试:

Begin
  SELECT ID into variable3 from BACKUP where column3 = var1;
Exception
When NO_DATA_FOUND Then
    DBMS_OUTPUT.PUT_LINE('ERROR: '||sqlerrm);
    Raise;  -- To ensure if this is the error, you will set get no_data_found raised... 
End;

【讨论】:

  • 异常错误堆栈会说明哪一行正在抛出异常。除了丢失行号引用之外,我没有看到添加另一个异常处理程序真正添加了什么?
  • 正如我所建议的那样,Raise 是为了不让你失去底线。它被添加到错误堆栈中。但无论如何,这是为了证明这一点,至于为什么会发生错误......
  • 谢谢!我实际上是在分析打开光标的查询。在某些情况下,此查询实际上没有返回任何数据。
【解决方案2】:

您的count_var 可能太高,即超过 120,因为它没有与光标相同的过滤器。如果backup 中有任何行,其中column1column2 为null,则您将获取太多次,并且在您用完数据时获取将返回null;然后您的内部select 将尝试匹配null,这将获得ORA-01403。

您也可能在backup 中没有匹配记录,其中column3 = var1。不清楚您是否有一致的数据。

但假设该部分有效,您可以在没有单独的count_var 的情况下循环光标:

open v_Cur for select column1, column2 from backup where ... ;
loop
  fetch v_Cur into var1,var2;
  exit when v_Cur%NOTFOUND;

  SELECT ID into variable3 from BACKUP where column3 = var1;
  UPDATE BACKUP SET column2 = var3;
end loop;
close v_cur;

当 fetch 用完游标的结果时,循环将退出。

不知道为什么你对这个过程有这么多的论据。看起来您只需要传入var3,而无需真正传回任何内容。 v_Cur 可以在声明部分声明为 cursor,而不是作为参数。

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 1970-01-01
    • 2016-04-03
    • 2017-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-20
    相关资源
    最近更新 更多