PL/SQL - 找到游标时的预操作

Posted

技术标签:

【中文标题】PL/SQL - 找到游标时的预操作【英文标题】:PL/SQL - Pre actions if cursor is found 【发布时间】:2015-03-20 13:25:50 【问题描述】:

我有一个像这样的简单光标:

CURSOR emp_cur
IS
  SELECT *
    FROM employee
    WHERE age > 20; 

在我的程序中,只有当光标中有员工时,我才想做一些预先操作。在该预操作之后,我处理所有行。

我需要这个,因为只有当该游标中存在员工时,我才需要清理一些表,否则我应该“返回”。

所以代码可以是:

OPEN emp_cur;
/* Here i need to do pre-action only if emp_cur has rows*/
IF /* has rows*/
THEN
  /* do some actions*/
END IF;

LOOP
  FETCH emp_cur INTO emp_rec;
  EXIT WHEN emp_cur%NOTFOUND;
END LOOP;

CLOSE emp_cur;

目前,我有一个“肮脏”的解决方案,可以在其中打开光标:

    首先检查是否有行 执行预操作并关闭 再次打开/获取以处理行,然后再次关闭

【问题讨论】:

如果您已经解决了您的问题,您应该将其作为答案发布,而不是编辑问题。 对不起,我已经删除了更新并写了答案。 【参考方案1】:

首先检查是否有行

在您FETCH之前,您无法知道这些行。

来自文档link,

在打开游标或游标变量之后但在第一个之前 获取,%FOUND 返回 NULL。在任何获取后,如果 最后一次提取返回一行,如果最后一次提取没有返回一个行,则返回 FALSE 行。

获取行后,在处理行之前,您可以使用 %FOUND

例如,

OPEN c1;
  LOOP
    FETCH c1 INTO my_ename, my_salary;
    IF c1%FOUND THEN  -- fetch succeeded
      -- Do something
    ELSE  -- fetch failed, so exit loop
      EXIT;
    END IF;
  END LOOP;

【讨论】:

这样,我不会为每次执行(FETCH)做“做某事”吗?我只需要进行一次预操作,然后……在每一行上循环。在我的情况下,预操作是一个 DELETE,循环需要插入“新”行。 @Mistre83,如果你想在第一行之前做一些特殊的动作,你可以在IF c1%FOUND THEN 里面多加一个 IF 子句,比如IF v_firstrow = TRUE THEN -- Do DELETE ... v_firstrow=FALSE; END IF; 之后... @987654325 @ @ruudvan 是的,这是我想做的事情……我不太喜欢它,但如果有其他方法,我会这样做:) @Mistre83,好吧,既然你已经取了,你当然可以“做点什么”,不是吗?这里“做某事”的上下文意味着您可以进行一些事务,因为前面的 PL/SQL 语句返回一个布尔值作为 TRUE。因此,您可以采取一些行动。祝你好运!【参考方案2】:

稍微思考一下,我已经编写了这个避免循环内 IF 的过程。我知道,这有点“奇怪”,但这是我认为唯一有效的方法:

OPEN emp_cur;
FECTH emp_cur INTO emp_rec;

IF emp_cur%FOUND
THEN
  -- pre actions
END IF;

LOOP
  EXIT WHEN emp_cur%NOTFOUND;
  -- do something in the loop
  FECTH emp_cur INTO emp_rec; -- First fetch was done before the if
END LOOP;

CLOSE emp_cur;

【讨论】:

不应该是emp_cur 而不是import_lav_cur 吗? 你是对的!从我的真实代码中删除并过去,对不起:)

以上是关于PL/SQL - 找到游标时的预操作的主要内容,如果未能解决你的问题,请参考以下文章

pl / sql如何使用带有游标的for循环进行更新操作

Oracle笔记4-pl/sql-分支/循环/游标/异常/存储/调用/触发器

PL/SQL 编程游标存储过程函数

orcale 之 PL/SQL的游标

PL/SQL 没有发现游标的数据异常

PL/SQL 游标不显示结果