显式打开和关闭游标

Posted

技术标签:

【中文标题】显式打开和关闭游标【英文标题】:Explicit Opening and Closing cursors 【发布时间】:2009-10-16 12:22:58 【问题描述】:

我一直在阅读有关数据库游标的内容,并且我看到的每一段示例代码都明确地打开和关闭了游标。我只用过几次,我从来没有这样做过。谁能告诉我为什么有必要这样做?我知道如果你不关闭游标,你会造成内存泄漏,但我从来没有打开过。

谢谢

【问题讨论】:

【参考方案1】:

您只需要打开和关闭显式游标。 Implicit cursors 具有由 Oracle 自动管理的优势。隐式游标示例:

DECLARE
   l_dept dept%rowtype;
BEGIN
   -- implicit SELECT INTO
   SELECT * INTO l_dept FROM dept WHERE deptno = :deptno;
   -- implicit LOOP
   FOR cc IN (SELECT emp.* FROM emp WHERE deptno = l_dept.deptno) LOOP
      dbms_output.put_line('emp='||cc.empno);
   END LOOP;
END;
/

隐式游标在代码中更加简洁,您不必担心关闭它们。我还发现将光标的代码放在实际使用的地方更清楚。我很少使用显式游标,只有当它们可以在包中的许多地方重用时(那为什么不把它放在一个 proc 中呢?)。

【讨论】:

SELECT * INTO l_dept FROM dept WHERE deptno = :deptno; +1,您对隐式游标的评论很到位。由于懒惰,我讨厌显式游标所需的额外编码。另一个好处:您不必检查数据不足的情况。处理完所有数据后,循环退出。【参考方案2】:

如果你的游标是全局的(我猜你在这不是问题的地方使用了本地游标,因为当它们超出范围时它们会被关闭)你必须明确地关闭它们。

不关闭全局游标存在几个问题

游标使用的内存没有被释放 您可以打开的游标的最大数量。最终您将无法创建另一个,因为您将打开最大数量的游标。

如果您问我为什么必须使用游标? - 有时您需要遍历行(例如使用常规 for 循环)。在面向集合的方法中你不能这样做 - 你必须使用光标。

【讨论】:

【参考方案3】:

这是一个很好的做法,因为您可以轻松获取任何特定查询(ROWCOUNT、NOTFOUND 等)的 SQL 状态,无论您是否同时运行了其他查询。此外,您可以在包中重用您的游标,创建其 ROWTYPE 的数据类型,对它们进行循环,以及各种好东西!

【讨论】:

以上是关于显式打开和关闭游标的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 游标简介

oracle游标的使用

oracle 学习游标

处理游标的四个步骤

打开和关闭游标和连接的建议做法

数据库错题库第八章8.4(游标可以多次使用,多次打开和关闭!)