Cursores
📝 ¿Qué es un cursor?
Section titled “📝 ¿Qué es un cursor?”Un cursor es un objeto que permite recorrer de manera secuencial un conjunto de datos, fila por fila. A diferencia de las consultas tradicionales que operan sobre conjuntos de datos completos, un cursor permite procesar cada registro de forma individual dentro de un bucle, lo que es útil para tareas que no se pueden realizar con operaciones basadas en conjuntos.
Para trabajar con cursores, se deben seguir estos pasos:
- Declarar el cursor (
DELCARE) - Abrir el cursor (
OPEN) - Leer los datos de la primera fila (
FETCH...INTO) - Recorrer las filas con un bucle (
WHILE @@FETCH_STATUS = 0) - Cerrar el cursor (
CLOSE) - Liberar los recursos (
DEALLOCATE)
📈 Estructura Básica
Section titled “📈 Estructura Básica”-- Declaración del cursorDECLARE <nombre_cursor> CURSOR FOR <sentencia_sql>
-- Apertura del cursorOPEN <nombre_cursor>
-- Lectura de la primera fila del cursorFETCH <nombre_cursor> INTO <lista_variables>
WHILE (@@FETCH_STATUS = 0) -- Recorrido de filas mientras la lectura sea exitosaBEGIN -- Procesamiento de la fila actual -- ...
-- Lectura de la siguiente fila del cursor FETCH <nombre_cursor> INTO <lista_variables>END
-- Cierre del cursorCLOSE <nombre_cursor>
-- Liberación de los recursos del cursorDEALLOCATE <nombre_cursor>Ejemplo 1
Section titled “Ejemplo 1”Este ejemplo muestra cómo declarar, abrir y recorrer un cursor para imprimir los detalles de los artículos.
DECLARE @ID INT, @nom VARCHAR(255), @descripcion VARCHAR(255), @precio VARCHAR(255);
DECLARE cArticulos CURSOR FOR SELECT ID, nom, precio, descripcion FROM Articulos;
OPEN cArticulos;
FETCH NEXT FROM cArticulos INTO @ID, @nom, @descripcion, @precio;
WHILE @@FETCH_STATUS = 0BEGIN PRINT @nom + ', ' + @descripcion + ', ' + @precio; FETCH NEXT FROM cArticulos INTO @ID, @nom, @descripcion, @precio;END;
CLOSE cArticulos;DEALLOCATE cArticulos;La función @@FETCH_STATUS indica el estado de la última instrucción FETCH:
| Valor | Descripción |
|---|---|
0 | La instrucción FETCH se ejecutó correctamente. |
-1 | La instrucción FETCH falló o la fila estaba fuera del conjunto de resultados. |
-2 | La fila recuperada no existe. |
⚙️ Parámetros del Cursor
Section titled “⚙️ Parámetros del Cursor”Puedes modificar el comportamiento de un cursor con una serie de parámetros opcionales. La sintaxis completa para la declaración es:
DECLARE <nombre_cursor> CURSOR [ LOCAL | GLOBAL ] [ FORWARD_ONLY | SCROLL ] [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ] [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] [ TYPE_WARNING ]FOR <sentencia_sql>Ámbito: LOCAL o GLOBAL
Section titled “Ámbito: LOCAL o GLOBAL”LOCAL: El ámbito del cursor es local a la función, procedimiento almacenado o lote en el que fue creado. No es visible fuera de ese ámbito.GLOBAL: El cursor es visible para cualquier procedimiento, lote o trigger que se ejecute dentro de la misma conexión.
Nota:
Si no se especifica GLOBAL ni LOCAL, el valor predeterminado se controla mediante la opción de base de datos default to local cursor.
Desplazamiento: FORWARD_ONLY o SCROLL
Section titled “Desplazamiento: FORWARD_ONLY o SCROLL”FORWARD_ONLY: El cursor solo puede avanzar de la primera a la última fila. Solo permite la lectura en una dirección.SCROLL: Habilita todas las opciones de recuperación (FIRST,LAST,PRIOR,NEXT,RELATIVE,ABSOLUTE), lo que permite la lectura en cualquier dirección.
-- Ejemplo de cursor SCROLLDECLARE @ID INT, @nom VARCHAR(255), @descripcion VARCHAR(255), @precio VARCHAR(255);
DECLARE cArticulos CURSOR SCROLL FOR SELECT ID, nom, precio, descripcion FROM Articulos;
OPEN cArticulos;
-- Lectura de la primera filaFETCH NEXT FROM cArticulos INTO @ID, @nom, @descripcion, @precio;PRINT 'Primera fila: ' + @nom;
-- Lectura de la última filaFETCH LAST FROM cArticulos INTO @ID, @nom, @descripcion, @precio;PRINT 'Última fila: ' + @nom;
CLOSE cArticulos;DEALLOCATE cArticulos;Tipos de Cursores: STATIC, KEYSET, DYNAMIC y FAST_FORWARD
Section titled “Tipos de Cursores: STATIC, KEYSET, DYNAMIC y FAST_FORWARD”STATIC: Crea una copia de los datos entempdbal abrir el cursor. Los cambios en las tablas base no se reflejan en el cursor. No permite modificaciones.KEYSET: El conjunto de filas del cursor se fija cuando se abre. Los cambios en los valores de las filas son visibles, pero las inserciones o eliminaciones de filas no.DYNAMIC: El cursor refleja todos los cambios realizados en los datos subyacentes. El conjunto de resultados, el orden y los valores de las filas pueden cambiar con cada operaciónFETCH.FAST_FORWARD: Un cursorFORWARD_ONLYyREAD_ONLYcon optimizaciones de rendimiento. No puede usarse conSCROLLoFOR_UPDATE.
Concurrencia: READ_ONLY, SCROLL_LOCKS y OPTIMISTIC
Section titled “Concurrencia: READ_ONLY, SCROLL_LOCKS y OPTIMISTIC”READ_ONLY: Impide que se realicen actualizaciones a través del cursor. Es la opción predeterminada para cursores que no permiten actualizaciones.SCROLL_LOCKS: Garantiza que las actualizaciones y eliminaciones realizadas a través del cursor sean exitosas. Bloquea las filas al leerlas para evitar que otros usuarios las modifiquen. No se puede usar conFAST_FORWARDoSTATIC.OPTIMISTIC: Permite actualizaciones, pero verifica si la fila ha sido modificada por otro usuario desde que se leyó. Si se detecta un cambio, la operación fallará. Utiliza marcas de tiempo o sumas de comprobación. No se puede usar conFAST_FORWARD.