Para algunos, es una herramienta útil,
lo único cierto es que rompe con uno de los fundamentos con los que SQL SERVER
trabaja que es la Teoría de conjuntos,
por lo tanto muchos recomiendan no utilizarlo a menos que sea sumamente
necesario y no tengamos otra opción para resolver el problema que se nos
presenta. Hasta ahora, en lo personal, he logrado solventar todos los problemas
donde anteriormente se usaban cursores con consultas SQL y el tiempo de
respuesta se ha visto incrementado enormemente.
El funcionamiento es similar a
una iteración como DO..WHILE, WHILE, etc en los lenguajes de programación, solo
que necesitamos de una consulta. Nuevamente usaré AdventureWorks2012 para el ejemplo:
USE AdventureWorks2012;
--Declaramos las variables que
utilizaremos
DECLARE
@c TINYINT = 1, @a TINYINT=1
--Variable para almacenar los valores
del primer CURSOR
,@businessEntityID INT
, @creditCardID INT
, @modifiedDate DATETIME
--Variables para almacenar los valores
del segundo CURSOR
, @cardType VARCHAR(100)
, @cardNumber VARCHAR(25)
, @expMonth TINYINT
, @expYear SMALLINT
, @modifiedDate2 DATETIME
--Declaración del CURSOR
cPersonCreditCard
DECLARE
cPersonCreditCard CURSOR
FOR
SELECT
TOP 20 * FROM sales.PersonCreditCard
--Abrimos el CURSOR cPersonCreditCard
OPEN cPersonCreditCard
--FETCH para moverse entre las filas
del resultado del CURSOR.
FETCH NEXT FROM cPersonCreditCard
--INTO para almacenar los valores del
resultado del CURSOR en las variables indicadas.
--La cantidad de variables debe ser la
misma que la cantidad de columnas devueltas por
--el cursor así como los tipos de datos
deben ser similares o idénticos.
INTO @businessEntityID, @creditCardID, @modifiedDate
--Iniciamos con la iteración
preguntando si existen filas en el CURSOR
--0 indica que el resultado de la
instrucción FETCH se ejecutó correctamente.
WHILE @@FETCH_STATUS = 0
BEGIN
--Imprimimos las variables para ver el resultado.
PRINT '< Cursor
cPersonCreditCard: ' + CAST( @c AS VARCHAR )
PRINT '@businessEntityID:' +
CAST( @businessEntityID AS VARCHAR )
PRINT '@creditCardID: ' + CAST( @creditCardID AS VARCHAR )
PRINT '@modifiedDate: ' + CAST( @modifiedDate AS VARCHAR )
SET @c=@c+1
SET @a=1
--CURSOR ANIDADO cCreditCard para obtener otros valores.
DECLARE cCreditCard CURSOR FOR
SELECT CardType, CardNumber, ExpMonth, ExpYear, ModifiedDate
FROM sales.CreditCard WHERE CreditCardID = @creditCardID
--Abrimos el CURSOR cCreditCard
OPEN cCreditCard
--Nos posicionamos en la primera fila.
FETCH NEXT FROM cCreditCard
INTO
@cardType, @cardNumber, @expMonth, @expYear, @modifiedDate2
--Verificamos que la instrucción FETCH se
haya ejecutado correctamente.
WHILE @@FETCH_STATUS
= 0
BEGIN
--Imprimimos las variables del cursor cCreditCard
PRINT ' <<<Cursor cCreditCard: ' + CAST( @a AS VARCHAR )
PRINT
' @cardType:'
+ CAST( @cardType AS VARCHAR )
PRINT
' @cardNumber:
' + CAST( @cardNumber AS VARCHAR )
PRINT
' @expMonth: '
+ CAST( @expMonth AS VARCHAR )
PRINT
' @expYear:'
+ CAST( @expYear AS VARCHAR )
PRINT
'
@modifiedDate2: ' + CAST( @modifiedDate2 AS VARCHAR )
PRINT
'
>>>>>'
SET
@a=@a+1
--Nos movemos hacia la
siguiente fila del CURSOR cCreditCard
FETCH NEXT FROM cCreditCard
INTO
@cardType, @cardNumber, @expMonth, @expYear, @modifiedDate2
END -- Fin de la iteración del
CURSOR cCreditCard
CLOSE cCreditCard; --Cerramos el CURSOR
cCreditCard
DEALLOCATE cCreditCard; --Liberamos el CURSOR
PRINT '>>>>>>>>'
--Nos movemos hacia la siguiente fila del CURSOR
cPersonCreditCard
FETCH NEXT FROM cPersonCreditCard
INTO @creditCardID, @creditCardID, @modifiedDate
END -- Fin de la iteración del
CURSOR cPersonCreditCard
CLOSE cPersonCreditCard; --Cerramos el CURSOR
cPersonCreditCard
DEALLOCATE cPersonCreditCard; --Liberamos el CURSOR
cPersonCreditCard
Mi recomendación, solo utilícenlo
como ultimo recurso, debemos acostumbrarnos a las buenas prácticas y pensar en
el resultado como un conjunto de datos.
SALUDOS!
COMPARTE ESTA INFORMACION SI TE PARECIO INTERESANTE
0 comentarios:
Publicar un comentario