关于plsql:Oracle中显式游标和隐式游标有什么区别?

关于plsql:Oracle中显式游标和隐式游标有什么区别?

What is the difference between explicit and implicit cursors in Oracle?

我对 PL/SQL 中的光标术语有点生疏了。有人知道吗?


隐式游标是 Oracle 在您执行查询时为您"自动"创建的。编码更简单,但受到

的影响

  • 效率低下(ANSI 标准规定它必须提取两次以检查是否有多个记录)
  • 数据错误漏洞(如果你得到两行,它会引发一个 TOO_MANY_ROWS 异常)

例子

1
SELECT col INTO var FROM TABLE WHERE something;

显式游标是您自己创建的游标。它需要更多的代码,但提供了更多的控制 - 例如,如果您只想要第一条记录并且不关心是否还有其他记录,您可以只打开-获取-关闭。

例子

1
2
3
4
5
6
7
DECLARE  
  CURSOR cur IS SELECT col FROM TABLE WHERE something;
BEGIN
  OPEN cur;
  FETCH cur INTO var;
  CLOSE cur;
END;

显式游标在声明块中定义为:

1
2
3
4
5
DECLARE
CURSOR cur IS
  SELECT columns FROM TABLE WHERE condition;
BEGIN
...

一个隐式游标直接在代码块中实现:

1
2
3
4
5
...
BEGIN
   SELECT columns INTO variables FROM TABLE WHERE condition;
END;
...

回答第一个问题。直接来自 Oracle 文档

A cursor is a pointer to a private SQL
area that stores information about
processing a specific SELECT or DML
statement.


n


1.CURSOR:当 PLSQL 发出 sql 语句时,它会创建私有工作区
解析


显式游标是您声明的游标,例如:

1
2
CURSOR my_cursor IS
  SELECT table_name FROM USER_TABLES

隐式游标是为了支持您编写的任何内联 SQL(静态或动态)而创建的。


现在隐式游标比显式游标更有效。

http://www.oracle.com/technology/oramag/oracle/04-sep/o54plsql.html

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1205168148688


n


使用显式游标,您可以完全控制如何访问数据库中的信息。您决定何时打开游标、何时从游标中获取记录(因此从游标的 SELECT 语句中的一个或多个表中)获取多少记录,以及何时关闭游标。通过检查光标属性可以获得有关光标当前状态的信息。

有关详细信息,请参阅 http://www.unix.com.ua/orelly/oracle/prog2/ch06_03.htm。


n


游标是Oracle 表上的一个SELECTed 窗口,这意味着Oracle 表中存在一组记录,并且满足某些条件。游标也可以选择表的所有内容。使用游标,您可以操作 Oracle 列,在结果中为它们设置别名。隐式游标的示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
BEGIN
   DECLARE
      CURSOR C1
      IS
         SELECT DROPPED_CALLS FROM ALARM_UMTS;

      C1_REC   C1%ROWTYPE;
   BEGIN
      FOR C1_REC IN C1
      LOOP
         DBMS_OUTPUT.PUT_LINE ('DROPPED CALLS: ' || C1_REC.DROPPED_CALLS);
      END LOOP;
   END;
END;
/

使用 FOR ... LOOP... END LOOP 自动打开和关闭游标,当游标的记录全部分析完时。

一个显式游标的例子如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
BEGIN
   DECLARE
      CURSOR C1
      IS
         SELECT DROPPED_CALLS FROM ALARM_UMTS;

      C1_REC   C1%ROWTYPE;
   BEGIN
      OPEN c1;

      LOOP
         FETCH c1 INTO c1_rec;

         EXIT WHEN c1%NOTFOUND;

         DBMS_OUTPUT.PUT_LINE ('DROPPED CALLS: ' || C1_REC.DROPPED_CALLS);
      END LOOP;

      CLOSE c1;
   END;
END;
/

在显式游标中,您以显式方式打开和关闭游标,检查记录的存在并声明退出条件。


隐式游标只返回一条记录并被自动调用。但是,显式游标是手动调用的,可以返回多条记录。


n


Google 是您的朋友:http://docstore.mik.ua/orelly/oracle/prog2/ch06_03.htm

PL/SQL issues an implicit cursor
whenever you execute a SQL statement
directly in your code, as long as that
code does not employ an explicit
cursor. It is called an"implicit"
cursor because you, the developer, do
not explicitly declare a cursor for
the SQL statement.

An explicit cursor is a SELECT
statement that is explicitly defined
in the declaration section of your
code and, in the process, assigned a
name. There is no such thing as an
explicit cursor for UPDATE, DELETE,
and INSERT statements.


Oracle 数据库执行的每条 SQL 语句都有一个与之关联的游标,游标是用于存储处理信息的私有工作区。 Oracle 服务器为所有 DML 和 SELECT 语句隐式创建隐式游标。

您可以声明和使用显式游标来命名私有工作区,并访问其在程序块中存储的信息。


显式...

cursor foo 是 select * from blah;
开始
关闭光标时打开获取退出 yada yada yada

不要使用它们,使用隐式

光标 foo 是 select * from blah;

for n 在 foo 循环中
x = n.some_column
结束循环

我认为你甚至可以做到这一点

for n in (select * from blah) 循环...

坚持隐含,它们封闭自己,它们更具可读性,它们让生活变得轻松。


推荐阅读