2008-09-16 38 views
22

Estoy un poco oxidado en mi jerga de cursor en PL/SQL. Alguien sabe esto?¿Cuál es la diferencia entre los cursores explícitos e implícitos en Oracle?

+0

¿Algo diferente en términos de funcionalidad? –

+2

duplicado exacto: http://stackoverflow.com/questions/74010/what-is-the-difference-between-explicit-and-implicit-cursors-in-oracle – msw

+1

el "duplicado" al que se refiere no explica la primera parte de la pregunta: "qué es un cursor". –

Respuesta

34

Un cursor implícito es uno creado "automáticamente" para usted por Oracle cuando ejecuta una consulta. Es más fácil de código, pero sufre de

  • ineficiencia (el estándar ANSI especifica que se debe obtener dos veces para comprobar si hay más de un registro)
  • vulnerabilidad a errores en los datos (si alguna vez tienes dos filas , se lanza una excepción TOO_MANY_ROWS)

Ejemplo

SELECT col INTO var FROM table WHERE something; 

un cursor explícito es uno que crea usted mismo. Se necesita más código, pero le da más control; por ejemplo, puede abrir-buscar-cerrar si solo quiere el primer registro y no le importa si hay otros.

Ejemplo

DECLARE 
    CURSOR cur IS SELECT col FROM table WHERE something; 
BEGIN 
    OPEN cur; 
    FETCH cur INTO var; 
    CLOSE cur; 
END; 
+0

Esta respuesta es genial, con muchos detalles y fragmentos. Gracias –

+6

Esta respuesta es buena, y yo la votaría, excepto que dice que los cursores implícitos son ineficaces, lo que es falso: por lo general, son más eficientes que los cursores explícitos de hecho, en los casos en que son apropiados. –

+7

-1 porque el motivo de ineficiencia es falso, ya que una versión 7.x y la vulnerabilidad a los errores de datos es algo bueno en mi opinión. Si espera una fila, pero obtiene dos, es muy conveniente que la excepción TOO_MANY_ROWS lo advierta. –

4

Un cursor es una explícita se declara, como:

CURSOR my_cursor IS 
    SELECT table_name FROM USER_TABLES 

Un cursor implícito es una creada para apoyar cualquier SQL en línea se escribe (estática o dinámica).

16

Un cursor explícita se define como tal en un bloque de declaración:

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

un cursor implícito se implented directamente en un bloque de código:

... 
BEGIN 
    SELECT columns INTO variables FROM table where condition; 
END; 
... 
2

Con cursores explícitos, usted tiene el control completo sobre cómo acceder a la información en la base de datos. Usted decide cuándo ABRIR el cursor, cuando FETCH registra desde el cursor (y por lo tanto desde la tabla o tablas en la instrucción SELECT del cursor) cuántos registros recuperar y cuándo CERRAR el cursor. La información sobre el estado actual de su cursor está disponible mediante el examen de los atributos del cursor.

Ver http://www.unix.com.ua/orelly/oracle/prog2/ch06_03.htm para más detalles.

0

Cada instrucción SQL ejecutada por la base de datos Oracle tiene un cursor asociado a él, que es un área de trabajo privada para almacenar información de procesamiento. Los cursores implícitos son creados implícitamente por el servidor Oracle para todas las sentencias DML y SELECT.

Puede declarar y usar cursores explícitos para nombrar el área de trabajo privada y acceder a su información almacenada en su bloque de programa.

-2

Explicit ...

cursor foo es seleccionar * de blah; comenzar abierta fetch salida cuando cerca del cursor bla bla bla

no los usa, uso implícito

cursor foo es seleccionar * de bla;

para n en bucle foo x = n.some_column final del bucle

Creo que incluso se puede hacer esto

para n en (seleccionar * de bla) de bucle ...

Se adhieren a lo implícito, se cierran a sí mismos, son más legibles, hacen la vida más fácil.

2

Google es su amigo: http://docstore.mik.ua/orelly/oracle/prog2/ch06_03.htm

PL/SQL emite un cursor implícito cada vez que se ejecuta una instrucción SQL directamente en el código, siempre y cuando esa El código no emplea un cursor explícito. Se llama un cursor "implícito" porque usted, el desarrollador, hace no declara explícitamente un cursor para la instrucción SQL.

Un cursor explícito es una instrucción SELECT que se define explícitamente en la sección de declaración de su código y, en el proceso, le asigna un nombre . No existe un cursor explícito para las instrucciones UPDATE, DELETE, e INSERT.

+0

mejor aún;) http://www.google.com/search?hl=es&q=difference+between+an+explicit+cursor+and+an+implicit+cursor+site:stackoverflow.com – msw

3

Respondiendo a la primera pregunta. Directamente desde el Oracle documentation

Un cursor es un puntero a una zona privada de SQL que almacena información sobre el procesamiento de una específica SELECT o DML comunicado.

1

Un cursor es una ventana SELECCIONADA en una tabla de Oracle, esto significa un grupo de registros presentes en una tabla de Oracle y que cumplen ciertas condiciones. Un cursor también puede SELECCIONAR todo el contenido de una tabla. Con un cursor puede manipular las columnas de Oracle, aliasing en el resultado. Un ejemplo de cursor implícito es el siguiente:

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

Con bucle For ... ... LOOP END abrir y cerrar el cursor authomatically, cuando los registros del cursor han sido analizados todos.

Un ejemplo de cursor explícito es el siguiente:

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

En el cursor explícito de abrir y cerrar el cursor de una manera explícita, la comprobación de la presencia de registros e indicando una condición de salida.

1

El cursor implícito solo devuelve un registro y se invoca automáticamente. Sin embargo, los cursores explícitos se llaman manualmente y pueden devolver más de un registro.

4

1.CURSOR: Cuando PLSQL emite sentencias sql crea área de trabajo privada para analizar & ejecutar la instrucción sql se llama cursor.

2.IMPLICIT: Cuando cualquier bloque PL/SQLexecutable emite instrucción sql. PL/SQL crea cursor implícito y se gestiona automáticamente significa implcit abrir & se lleva a cabo el cierre. Se usa cuando la sentencia sql devuelve una sola fila. Tiene 4 atributos SQL% ROWCOUNT, SQL% FOUND, SQL% NOTFOUND, SQL% ISOPEN.

3.EXPLICIT: Se creó & administrado por el programador. Necesita cada tiempo explícito abierto, busque & cerrar. Se utiliza cuando la instrucción sql devuelve más de una fila. También tiene 4 atributos CUR_NAME% ROWCOUNT, CUR_NAME% FOUND, CUR_NAME% NOTFOUND, CUR_NAME% ISOPEN. Procesa varias filas mediante el uso de bucle. El programador también puede pasar el parámetro al cursor explícito.

  • Ejemplo: Cursor explícita

 

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

cursores implícitos requiere memoria intermedia anónimo.

Los cursores explícitos se pueden ejecutar una y otra vez usando su nombre. Se almacenan en un espacio de memoria definido por el usuario en lugar de almacenarse en una memoria anónima de búfer y, por lo tanto, se puede acceder fácilmente después.

1

Sé que esta es una vieja pregunta, sin embargo, creo que sería bueno agregar un ejemplo práctico para mostrar la diferencia entre los dos desde el punto de vista del rendimiento.

Desde el punto de vista del rendimiento, los cursores implícitos son más rápidos.

Veamos la diferencia de rendimiento entre los dos:

SQL> SET SERVEROUTPUT ON 
SQL> DECLARE 
    2 l_loops NUMBER := 100000; 
    3 l_dummy dual.dummy%TYPE; 
    4 l_start NUMBER; 
    5 
    6 CURSOR c_dual IS 
    7  SELECT dummy 
    8  FROM dual; 
    9 BEGIN 
10 l_start := DBMS_UTILITY.get_time; 
11 
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 
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. 

Por lo tanto, una diferencia significativa es claramente visible.

Más ejemplos here.

0

Como se indica en otras respuestas, los cursores implícitos son más fáciles de usar y menos propensos a errores.

Y Implicit vs. Explicit Cursors in Oracle PL/SQL muestra que los cursores implícitos son hasta dos veces más rápidos que los explícitos también.

Es extraño que nadie había mencionado Implicit FOR LOOP Cursor:

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; 

Otro ejemplo de SO: PL/SQL FOR LOOP IMPLICIT CURSOR.

Es mucho más corto que la forma explícita.

Esto también proporciona una buena solución para updating multiple tables from CTE.

Cuestiones relacionadas