如何在Oracle PL/SQL游标中找到记录数?

aw *_*rud 8 oracle plsql stored-procedures

这是我的光标:

CURSOR C1 IS SELECT * FROM MY_TABLE WHERE SALARY < 50000 FOR UPDATE;
Run Code Online (Sandbox Code Playgroud)

我立即打开光标,以便在我的程序期间锁定这些记录.

我希望在我的光标中有<2条记录时引发应用程序错误.使用C1%ROWCOUNT属性失败,因为它只计算到目前为止已提取的数字.

这个用例的最佳模式是什么?我是否需要创建一个虚拟的MY_TABLE%ROWTYPE变量,然后遍历光标以获取它们并保持计数,或者是否有更简单的方法?如果这是这样做的方法,那么取出光标中的所有行都会隐式关闭它,从而解锁这些行,或者它会保持打开状态,直到我明确地关闭它,即使我已经将它们全部取出了?

我需要确保光标对于超出此计数的各种其他任务保持打开状态.

Sho*_*ace 6

注意:我只是重新阅读你的问题..如果只有1条记录,你想失败...我会在片刻发布一个新的更新..

我们从这里开始..

Oracle®DatabasePL/SQL用户指南和参考10g第2版(10.2)部件号B14261-01 参考

打开游标时,所有行都被锁定,而不是在获取它们时.提交或回滚事务时,行将被解锁.由于行不再被锁定,因此在提交后无法从FOR UPDATE游标中获取.

所以你不必担心记录解锁.

所以试试这个..

declare 
  CURSOR mytable_cur IS SELECT * FROM MY_TABLE WHERE SALARY < 50000 FOR UPDATE;

  TYPE mytable_tt IS TABLE OF mytable_cur %ROWTYPE
    INDEX BY PLS_INTEGER;

  l_my_table_recs mytable_tt;
  l_totalcount NUMBER;
begin

   OPEN mytable_cur ;
   l_totalcount := 0;

   LOOP
      FETCH mytable_cur 
      BULK COLLECT INTO l_my_table_recs LIMIT 100;

      l_totalcount := l_totalcount + NVL(l_my_table_recs.COUNT,0);

      --this is the check for only 1 row..
      EXIT WHEN l_totalcount < 2;

      FOR indx IN 1 .. l_my_table_recs.COUNT
      LOOP
         --process each record.. via l_my_table_recs (indx)

      END LOOP;

      EXIT WHEN mytable_cur%NOTFOUND;
   END LOOP;

   CLOSE mytable_cur ;
end;
Run Code Online (Sandbox Code Playgroud)

替代答案 我读到你回答开始并认为你想要退出,如果有超过1行..不完全一个..所以这是我以前的答案.

2种简单的方法来检查只有1条记录.

选项1 - 显式提取

declare 
  CURSOR C1 IS SELECT * FROM MY_TABLE WHERE SALARY < 50000 FOR UPDATE;
  l_my_table_rec C1%rowtype;
  l_my_table_rec2 C1%rowtype;
begin

    open C1;
    fetch c1 into l_my_table_rec;

    if c1%NOTFOUND then
       --no data found
    end if;

    fetch c1 into l_my_table_rec2;
    if c1%FOUND THEN
      --i have more then 1 row
    end if;
    close c1;

  -- processing logic

end;
Run Code Online (Sandbox Code Playgroud)

我希望你明白这个主意.

选项2 - 例外捕获

declare 
  CURSOR C1 IS SELECT * FROM MY_TABLE WHERE SALARY < 50000 FOR UPDATE;
  l_my_table_rec C1%rowtype;
begin
  begin
    select * 
      from my_table
      into l_my_table_rec
     where salary < 50000
       for update;
  exception
    when too_many_rows then
      -- handle the exception where more than one row is returned
    when no_data_found then
      -- handle the exception where no rows are returned
    when others then raise;
  end;

  -- processing logic
end;
Run Code Online (Sandbox Code Playgroud)

另外 请记住:使用显式游标..您可以将光标记录中的变量%TYPE,而不是原始表格.

当您在查询中加入时,这尤其有用.

此外,请记住,您可以使用更新表中的行

UPDATE table_name
SET set_clause
WHERE CURRENT OF cursor_name;
Run Code Online (Sandbox Code Playgroud)

类型语句,但我只会在你没有"获取"第二行的情况下才能工作.


有关游标FOR循环的更多信息,请尝试 这里