validar vacio recorrer procedimientos open imprimir implicito formas cursores almacenados oracle plsql

vacio - recorrer cursor oracle



¿Cuál es la diferencia entre los cursores explícitos e implícitos en Oracle? (15)

Estoy un poco oxidado en mi jerga de cursor en PL / SQL. Alguien sabe esto?


Un cursor explícito es uno que declaras, como:

CURSOR my_cursor IS SELECT table_name FROM USER_TABLES

Un cursor implícito es uno creado para admitir cualquier SQL en línea que escriba (ya sea estático o dinámico).


Un cursor explícito 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 implementa directamente en un bloque de código:

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


Con los cursores explícitos, tiene control total 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.


Cada instrucción SQL ejecutada por la base de datos Oracle tiene un cursor asociado, 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.



Explícito...

cursor foo es select * from blah; comenzar la salida de búsqueda abierta cuando el cursor cercano yada yada yada

no los uses, usa implícito

cursor foo es select * from blah;

para n en foo loop x = n.some_column end loop

Creo que incluso puedes hacer esto

para n en (seleccione * de bla) ciclo ...

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


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

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

Ejemplo

SELECT col INTO var FROM table WHERE something;

Un cursor explícito es uno que creas tú 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;


En respuesta a la primera pregunta. Directamente de la documentación de Oracle

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


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

PL / SQL emite un cursor implícito cada vez que ejecuta una instrucción SQL directamente en su código, siempre que ese código no emplee un cursor explícito. Se denomina cursor "implícito" porque usted, el desarrollador, no declara explícitamente un cursor para la instrucción SQL.

Un cursor explícito es una declaració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.


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 FOR ... LOOP ... END LOOP abre y cierra el cursor automáticamente, cuando se han analizado todos los registros del cursor.

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, abre y cierra el cursor de una manera explícita, verificando la presencia de registros y estableciendo una condición de salida.


1.CURSOR: Cuando PLSQL emite sentencias SQL, crea un área de trabajo privada para analizar y ejecutar la instrucción sql que 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 que se produce implcit open & close. Se usa cuando la sentencia sql devuelve solo una fila. Tiene 4 atributos SQL% ROWCOUNT, SQL% FOUND, SQL% NOTFOUND, SQL% ISOPEN.

3.EXPLICIT: es creado y administrado por el programador. Necesita cada vez abrir, abrir y cerrar explícitamente. Se usa 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 puede pasar el parámetro también al cursor explícito.

  • Ejemplo: Cursor explícito

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;


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.


Los cursores implícitos requieren memoria de búfer anónima.

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.


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.

Entonces, una diferencia significativa es claramente visible.

Más ejemplos aquí .


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

Y cursores implícitos frente a explícitos en 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 haya mencionado el Cursor FOR LOOP implícito :

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 en 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 actualizar varias tablas de CTE .