Cursores en Transact SQL
Un cursor es una variable que nos permite recorrer con un conjunto de resultados obtenido a
través de una sentencia SELECT fila a fila.
Cuando trabajemos con cursores debemos seguir los siguientes pasos.
Declarar el cursor, utilizando DECLARE
Abrir el cursor, utilizando OPEN
Leer los datos del cursor, utilizando FETCH ... INTO
Cerrar el cursor, utilizando CLOSE
Liberar el cursor, utilizando DEALLOCATE
La sintaxis general para trabajar con un cursor es la siguiente.
-- Declaración del cursor
DECLARE <nombre_cursor> CURSOR
FOR
<sentencia_sql>
-- apertura del cursor
OPEN <nombre_cursor>
-- Lectura de la primera fila del cursor
FETCH <nombre_cursor> INTO <lista_variables>
WHILE (@@FETCH_STATUS = 0)
BEGIN
-- Lectura de la siguiente fila de un cursor
FETCH <nombre_cursor> INTO <lista_variables>
...
END -- Fin del bucle WHILE
-- Cierra el cursor
CLOSE <nombre_cursor>
-- Libera los recursos del cursor
DEALLOCATE <nombre_cursor>
El siguente ejemplo muestra el uso de un cursor.
-- Declaracion de variables para el cursor
DECLARE @ID_PRODUCTO INT
DECLARE @DESCRIPCION VARCHAR(255)
-- Declaración del cursor
DECLARE CPRODUCTO CURSOR FOR
SELECT ID_PRODUCTO, DESCRIPCION FROM [Link]
-- Apertura del cursor
OPEN CPRODUCTO
-- Lectura de la primera fila del cursor
FETCH CPRODUCTO INTO @ID_PRODUCTO, @DESCRIPCION
-- La instrucción FETCH se ejecutó correctamente.
WHILE (@@FETCH_STATUS = 0 )
BEGIN
PRINT @Nombre + ' ' + @Apellido1 + ' ' + @Apellido2
-- Lectura de la siguiente fila del cursor
FETCH CPRODUCTO INTO @ID_PRODUCTO, @DESCRIPCION
END
-- Cierre del cursor
CLOSE CPRODUCTO
-- Liberar los recursos
DEALLOCATE CPRODUCTO
Cuando trabajamos con cursores, la funcion @@FETCH_STATUS nos indica el estado de la
última instrucción FETCH emitida, los valores posibles son:
Valor
Descripción
devuelto
0 La instrucción FETCH se ejecutó correctamente.
La instrucción FETCH no se ejecutó correctamente o la fila estaba más allá del
-1
conjunto de resultados.
-2 Falta la fila recuperada.
Ejmplo de como realizer un ciclo dentro de otro ciclo.
DECLARE @ID_PRODUCTO INT
DECLARE @DESCRIPCION VARCHAR(255)
DECLARE @FETCH_STATUS1 INT
DECLARE @FETCH_STATUS2 INT
DECLARE @FECHA_DESDE DATE
DECLARE @FECHA_HASTA DATE
DECLARE @PRECIO DECIMAL(18,2)
DECLARE CPRODUCTO CURSOR FOR
SELECT ID_PRODUCTO, DESCRIPCION FROM [Link]
OPEN CPRODUCTO
FETCH CPRODUCTO INTO @ID_PRODUCTO, @DESCRIPCION
SET @FETCH_STATUS1= @@FETCH_STATUS
WHILE @FETCH_STATUS1 = 0 BEGIN
PRINT CONCAT(@ID_PRODUCTO , CHAR(9) , @DESCRIPCION )
DECLARE CPRODUCTOPRECIO CURSOR FOR
SELECT DESDE, HASTA, PRECIO FROM DBO.LISTA_PRECIO
WHERE ID_PRODUCTO = @ID_PRODUCTO
ORDER BY DESDE
OPEN CPRODUCTOPRECIO
FETCH CPRODUCTOPRECIO INTO @FECHA_DESDE, @FECHA_HASTA, @PRECIO
SET @FETCH_STATUS1 = @@FETCH_STATUS
PRINT CONCAT(CHAR(13),CHAR(9),'FECHA DESDE', CHAR(9), 'FECHA HASTA', CHAR(9)
,'PRECIO')
WHILE @FETCH_STATUS1 = 0 BEGIN
PRINT CONCAT(CHAR(13),CHAR(9),@FECHA_DESDE, CHAR(9), @FECHA_HASTA,
CHAR(9) ,@PRECIO)
FETCH CPRODUCTOPRECIO INTO @FECHA_DESDE, @FECHA_HASTA, @PRECIO
SET @FETCH_STATUS1 = @@FETCH_STATUS
END
PRINT CHAR(13)
CLOSE CPRODUCTOPRECIO
DEALLOCATE CPRODUCTOPRECIO
FETCH CPRODUCTO INTO @ID_PRODUCTO, @DESCRIPCION
SET @FETCH_STATUS1= @@FETCH_STATUS
END
CLOSE CPRODUCTO
DEALLOCATE CPRODUCTO