Hoy no vamos a ver APEX en si mismo sino cómo podemos manejar los cursores en PL/SQL.

En PL/SQL, un cursor es una estructura que te permite recorrer un conjunto de filas recuperadas por una sentencia SELECT.

Hay dos tipos de cursores: explícitos e implícitos.

Cursor Implícito

FOR empleado_rec IN (SELECT ename, sal FROM emp) LOOP
DBMS_OUTPUT.PUT_LINE('Nombre: ' || empleado_rec.ename || ', Salario: ' || empleado_rec.sal);
END LOOP;

En este ejemplo, el cursor implícito se crea automáticamente al ejecutar la sentencia SELECT. Luego, se recorre el conjunto de resultados utilizando un bucle FOR.

Cursor Explícito

DECLARE
  CURSOR empleados_cursor IS
  SELECT ename, sal FROM emp;
  empleado_rec empleados_cursor%ROWTYPE;
BEGIN
  OPEN empleados_cursor;
  LOOP
   FETCH empleados_cursor INTO empleado_rec;
   EXIT WHEN empleados_cursor%NOTFOUND;
   DBMS_OUTPUT.PUT_LINE('Nombre: ' || empleado_rec.ename || ', Salario: ' || empleado_rec.sal);
END LOOP;
  CLOSE empleados_cursor;
END;

En este ejemplo, se crea un cursor explícito llamado «empleados_cursor». Se abre el cursor, se recorren las filas con un bucle, y luego se cierra el cursor.

Los cursores son útiles para manipular conjuntos de resultados en Oracle. Podemos utilizarlos para procesar datos fila por fila, realizar operaciones basadas en condiciones y realizar tareas más avanzadas en el manejo de datos de la base de datos.

Diferencias entre los dos cursores

La principal diferencia entre los cursores implícitos y explícitos en PL/SQL radica en cómo se declaran y manejan.

1. Cursor Implícito:
Declaración: Se crea automáticamente cuando ejecutas una sentencia SELECT.
Sintaxis de Recorrido: Utiliza un bucle FOR para recorrer las filas directamente.

2. Cursor Explícito:
Declaración: Se define y declara explícitamente antes de su uso.
Sintaxis de Recorrido: Requiere abrir, fetchear y cerrar manualmente.

Los cursores implícitos son más simples de usar y no requieren una declaración explícita, pero pueden ser menos flexibles en términos de control. Los cursores explícitos brindan un mayor control y flexibilidad, pero a expensas de una sintaxis más detallada y un manejo manual más complejo. La elección entre ellos depende de los requisitos específicos de tu lógica de programación y manipulación de datos.

Ventajas y Desventajas

Vamos a considerar un escenario en el que necesitamos procesar empleados cuyos salarios superen un cierto umbral. En este caso, podríamos comparar cómo sería implementar esto con un cursor implícito y un cursor explícito.

Cursor Implícito:

Ventajas del Cursor Implícito:
– Sintaxis más concisa y fácil de entender.
– Automáticamente se ocupa de la apertura, fetch y cierre.

Desventajas del Cursor Implícito:
– Menos control explícito sobre la manipulación del cursor.
– Limitado en términos de personalización y manejo de errores.

Cursor Explícito:

Ventajas del Cursor Explícito:
– Mayor control sobre la apertura, fetch, y cierre del cursor.
– Posibilidad de realizar acciones específicas antes o después del fetch.

Desventajas del Cursor Explícito:
– Sintaxis más extensa y detallada.
– Requiere manejo manual de apertura, fetch, y cierre.

Elección:
– Si la operación es simple y no requiere un control detallado del cursor, el cursor implícito puede ser más adecuado por su simplicidad.
– Si se necesita un mayor control sobre el cursor, como realizar acciones específicas antes o después del fetch, el cursor explícito ofrece más flexibilidad.

En general, la elección entre ambos tipos de cursores depende de la complejidad de la lógica requerida y del nivel de control que necesitas sobre la manipulación de los datos en la base de datos Oracle.

Manejo de Errores

Se puede manejar errores en ambos tipos de cursores, ya sean implícitos o explícitos, utilizando bloques de manejo de excepciones en PL/SQL.

Veamos un código simple a modo de ejemplo de cómo manejar errores en ambas situaciones:

Manejo de Errores con Cursor Implícito:

BEGIN
  FOR empleado_rec IN (SELECT ename, sal FROM emp) LOOP
BEGIN
  -- Lógica de procesamiento aquí
  DBMS_OUTPUT.PUT_LINE('Nombre: ' || empleado_rec.ename || ', Salario: ' || empleado_rec.sal);
EXCEPTION
WHEN OTHERS THEN
  DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
END;
END LOOP;
END;

Manejo de Errores con Cursor Explícito:

DECLARE
  CURSOR empleados_cursor IS
    SELECT ename, sal FROM emp;
    empleado_rec empleados_cursor%ROWTYPE;
BEGIN
  OPEN empleados_cursor;
  LOOP
   BEGIN
     FETCH empleados_cursor INTO empleado_rec;
     EXIT WHEN empleados_cursor%NOTFOUND;

-- Lógica de procesamiento aquí
  DBMS_OUTPUT.PUT_LINE('Nombre: ' || empleado_rec.ename || ', Salario: ' || empleado_rec.sal);
EXCEPTION
WHEN OTHERS THEN
  DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
  END;
  END LOOP;
  CLOSE empleados_cursor;
END;

Ambos ejemplos incluyen un bloque «BEGIN…EXCEPTION…END» para manejar cualquier excepción que pueda ocurrir durante el procesamiento del cursor. Dentro de este bloque, puedes personalizar el manejo de errores según tus necesidades.

Recuerda que es una buena práctica capturar excepciones de manera específica (en lugar de capturar «WHEN OTHERS») para manejar diferentes tipos de errores de manera más precisa.