28

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

4

16 回答 16

45

隐式游标是 Oracle 在您执行查询时“自动”为您创建的游标。编码更简单,但存在以下问题

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

例子

SELECT col INTO var FROM table WHERE something;

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

例子

DECLARE   
  CURSOR cur IS SELECT col FROM table WHERE something; 
BEGIN
  OPEN cur;
  FETCH cur INTO var;
  CLOSE cur;
END;
于 2008-09-16T19:47:35.797 回答
20

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

DECLARE 
CURSOR cur IS 
  SELECT columns FROM table WHERE condition;
BEGIN
...

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

...
BEGIN
   SELECT columns INTO variables FROM table where condition;
END;
...
于 2008-09-16T16:18:07.953 回答
4

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

CURSOR my_cursor IS
  SELECT table_name FROM USER_TABLES

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

于 2008-09-16T16:13:56.000 回答
4

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

游标是指向私有 SQL 区域的指针,该区域存储有关处理特定 SELECT 或 DML 语句的信息。

于 2010-05-13T09:32:22.197 回答
4

1.CURSOR:当PLSQL发出sql语句时,它会创建私有工作区来解析和执行sql语句,称为游标。

2.IMPLICIT:当任何PL/SQL可执行块发出sql语句时。PL/SQL 创建隐式游标并自动管理意味着隐式打开和关闭发生。当sql语句只返回一行时使用。它有4个属性SQL%ROWCOUNT、SQL%FOUND、SQL%NOTFOUND、SQL%ISOPEN。

3.EXPLICIT:由程序员创建和管理。它每次都需要显式打开、获取和关闭。当 sql 语句返回多于一行时使用它。它还有 4 个属性 CUR_NAME%ROWCOUNT、CUR_NAME%FOUND、CUR_NAME%NOTFOUND、CUR_NAME%ISOPEN。它使用循环处理几行。程序员也可以将参数传递给显式游标。

  • 示例:显式光标

 

declare 
   cursor emp_cursor 
   is 
   select id,name,salary,dept_id 
   from employees; 
   v_id employees.id%type; 
   v_name employees.name%type; 
   v_salary employees.salary%type; 
   v_dept_id employees.dept_id%type; 
   begin 
   open emp_cursor; 
   loop 
   fetch emp_cursor into v_id,v_name,v_salary,v_dept_id; 
   exit when emp_cursor%notfound;
   dbms_output.put_line(v_id||', '||v_name||', '||v_salary||','||v_dept_id); 
   end loop;                    
   close emp_cursor; 
   end;
于 2012-02-13T09:27:59.203 回答
4

隐式游标需要匿名缓冲内存。

显式游标可以通过使用它们的名称一次又一次地执行。它们存储在用户定义的内存空间中,而不是存储在匿名缓冲内存中,因此以后可以轻松访问。

于 2012-07-04T06:59:11.737 回答
3

如今,隐式游标比显式游标更有效。

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

于 2008-09-17T14:46:35.047 回答
3

从性能的角度来看,隐式游标更快。

让我们比较显式和隐式游标的性能:

SQL> DECLARE
  2    l_loops  NUMBER := 100000;
  3    l_dummy  dual.dummy%TYPE;
  4    l_start  NUMBER;
  5    -- explicit cursor declaration
  6    CURSOR c_dual IS
  7      SELECT dummy
  8      FROM   dual;
  9  BEGIN
 10    l_start := DBMS_UTILITY.get_time;
 11    -- explicitly open, fetch and close the cursor
 12    FOR i IN 1 .. l_loops LOOP
 13      OPEN  c_dual;
 14      FETCH c_dual
 15      INTO  l_dummy;
 16      CLOSE c_dual;
 17    END LOOP;
 18
 19    DBMS_OUTPUT.put_line('Explicit: ' ||
 20                         (DBMS_UTILITY.get_time - l_start) || ' hsecs');
 21
 22    l_start := DBMS_UTILITY.get_time;
 23    -- implicit cursor for loop
 24    FOR i IN 1 .. l_loops LOOP
 25      SELECT dummy
 26      INTO   l_dummy
 27      FROM   dual;
 28    END LOOP;
 29
 30    DBMS_OUTPUT.put_line('Implicit: ' ||
 31                         (DBMS_UTILITY.get_time - l_start) || ' hsecs');
 32  END;
 33  /
Explicit: 332 hsecs
Implicit: 176 hsecs

PL/SQL procedure successfully completed.

因此,明显的差异是显而易见的。隐式游标比显式游标快得多。

更多示例在这里

于 2015-03-09T08:59:34.277 回答
2

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

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

于 2008-09-16T17:08:35.370 回答
1

谷歌是你的朋友: http ://docstore.mik.ua/orelly/oracle/prog2/ch06_03.htm

每当您直接在代码中执行 SQL 语句时,只要该代码不使用显式游标,PL/SQL 就会发出隐式游标。它被称为“隐式”游标,因为开发人员没有为 SQL 语句显式声明游标。

显式游标是在代码的声明部分中显式定义的 SELECT 语句,并在此过程中分配了一个名称。没有用于 UPDATE、DELETE 和 INSERT 语句的显式游标。

于 2010-05-13T05:13:38.680 回答
1

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

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 当游标的记录全部分析完毕后,您可以自动打开和关闭游标。

显式游标的示例如下:

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;
/

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

于 2010-05-14T09:51:14.447 回答
1

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

于 2010-06-29T05:59:49.697 回答
1

如其他答案所述,隐式游标更易于使用且不易出错。

Oracle PL/SQL 中的隐式游标与显式游标表明隐式游标也比显式游标快两倍。

奇怪的是还没有人提到隐式 FOR LOOP 光标

begin
  for cur in (
    select t.id from parent_trx pt inner join trx t on pt.nested_id = t.id
    where t.started_at > sysdate - 31 and t.finished_at is null and t.extended_code is null
  )
  loop
    update trx set finished_at=sysdate, extended_code = -1 where id = cur.id;
    update parent_trx set result_code = -1 where nested_id = cur.id;
  end loop cur;
end;

SO的另一个例子:PL/SQL FOR LOOP IMPLICIT CURSOR

它比显式形式短得多。

这也为从 CTE 更新多个表提供了一个很好的解决方法。

于 2017-11-16T17:50:41.037 回答
1

在 PL/SQL 中,游标是指向该上下文区域的指针。它包含处理语句所需的所有信息。

隐式游标: 当 SQL 语句没有显式游标时,Oracle 会自动创建隐式游标。程序员无法控制隐式游标及其中的信息。

显式游标: 显式游标是程序员定义的游标,用于获得对上下文区域的更多控制。应在 PL/SQL 块的声明部分中定义显式游标。它是在返回多行的 SELECT 语句上创建的。

创建显式游标的语法是:

CURSOR cursor_name IS select_statement; 
于 2019-04-23T14:36:39.950 回答
0

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

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

于 2008-09-17T00:56:37.163 回答
-2

明确...

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

不要使用它们,使用隐式

光标 foo 是 select * from blah;

for n in foo 循环 x = n.some_column 结束循环

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

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

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

于 2008-09-17T05:20:39.650 回答