Documentos de Académico
Documentos de Profesional
Documentos de Cultura
CURSORES DE TRANSACT-SQL
Una de las caractersticas que definen las bases
de datos relacionales es que las operaciones se
ejecutan sobre un conjunto de filas. Un conjunto
puede estar vaco, o contener una sola fila, pero
aun as se considera un conjunto. Esto es
necesario y til en operaciones relacionales, pero
en algunas ocasiones puede no ser conveniente
para las aplicaciones.
Por ejemplo dado que no hay un modo de apuntar
a una fila especfica de un conjunto, mostrar cada
vez una fila al usuario puede ser difcil. E incluso
aunque las extensiones al SQL estndar
proporcionadas por Transact-SQL hace al SQL
mas programable, aun existen operaciones
difciles, caras o simplemente imposibles de
realizar sobre un conjunto base.
Para manejar estas situaciones, SQL admite los
cursores. Un cursor es un objeto que apunta a
una fila especfica dentro de un conjunto.
Dependiendo de la naturaleza del cursor que cree,
puede mover el cursor por el conjunto y modificar
o borrar datos.
Los cursores Tansact-SQL se crean utilizando el
comando DECLARE CURSOR. Tanto el objeto
cursor como el conjunto de filas al que apunta
existen en el servidor. Este se denomina un
cursor de lado de servidor. Cuando utilice un
cursor de este tipo desde una aplicacin
conectada a SQL Server por una red, cada
operacin sobre el cursor requiere de un viaje a
travs de la red.
El conjunto de filas a las que apunta el cursor se
define por un comando SELECT. Existen algunas
restricciones sobre la sentencia SELECT cuando se
crea un cursor Transact-SQL:
No puede devolver mltiples conjunto de
resultados.
No puede contener la clusula INTO para crear
una nueva tabla.
No puede contener clusulas COMPUTE o
COMPUTE BY utilizadas para agregar resultados.
Caractersticas de los Cursores
Transact-SQL admite varios tipos diferentes de
cursores. Ordenarlos por las caractersticas de
cada tipo puede ser confuso, pero resulta mas
fcil si piensa en cada tipo en trminos de tres
caractersticas mas o menos independientes de
los cursores: su habilidad para reflejar los
cambios de los datos subyacentes, su habilidad
para moverse a travs del conjunto de filas, y su
habilidad para modificar el conjunto de filas.
Reflejar cambios
Cuando un cursor refleja los cambios realizados
sobre los datos subyacentes nos referimos a ello
WHERE
FOR sentencia_seleccion
[FOR UPDATE [OF nombre_columnas]]
FROM
Si
su
cursor
es
FORWARD_ONLY
o
FAST_FORWARD, la unica palabra clave de
posicionamiento que puede utilizar es NEXT. En
realidad, si su cursor es de alguno de los tipos
anteriores, no es necesario NEXT. SQL Server
asume que todo FETCH es un FETCH NEXT
En el primer ejemplo de cursores si lo
modificamos para que tenga esta apariencia, nos
mostrara todas las filas:
USE NorthWind
GO
-- Crear el cursor
DECLARE cursorSimple CURSOR
LOCAL
FOR SELECT CompanyName FROM Customers
-- Crea el conjunto de cursor
OPEN cursorSimple
-- Recupera una fila (la primera)
FETCH cursorSimple
WHILE @@FETCH_STATUS=0
FETCH cursorSimple
-- Cierra el conjunto de cursor
CLOSE cursorSimple
-- Libera el cursor
DEALLOCATE cursorSimple
GO
Utilizando
FIREHOSE
FETCH
NEXT
con
un
cursor
USE NorthWind
GO
DECLARE cursorSimple CURSOR
LOCAL
FAST_FORWARD
FOR
SELECT CompanyName FROM Customers
DECLARE @elNombre char(20)
DECLARE @contador int
OPEN cursorSimple
-- Muestra 6 filas
SET @contador = 1
WHILE @contador <= 6
BEGIN
FETCH cursorSimple INTO @elNombre
PRINT RTRIM(@elNombre) +
' --> es el nombre ' + LTRIM(STR(@contador))
SET @contador = @contador + 1
END
CLOSE cursorSimple
DEALLOCATE cursorSimple
GO
USE NorthWind
GO
DECLARE cursorSimple CURSOR
LOCAL
FOR
SELECT CustomerId, CompanyName, Region
FROM TblClientes
DECLARE @codigo char(5),
@nombre varchar(40), @region varchar(15)
OPEN cursorSimple
-- Lee la primera fila
FETCH cursorSimple
INTO @codigo,@nombre,@region
-- Si no hay error
WHILE (@@FETCH_STATUS=0)
BEGIN
-- si el campo @region es NULO
IF (@region IS NULL)
BEGIN
-- Cambia el campo Region(NULL)
UPDATE TblClientes
SET Region = 'Ya no es NULL'
WHERE CURRENT OF cursorSimple
-- Insertamos una nueva Fila en la tabla
-- TmpPrueba con los clientes
-- actualizados
INSERT TmpPrueba
VALUES(@codigo,@nombre)
END
-- Leemos la siguiente fila
FETCH cursorSimple
INTO @codigo,@nombre,@region
END
-- Cerramos y Liberamos el cursor
CLOSE cursorSimple
DEALLOCATE cursorSimple
GO
-- Verificando las Actualizaciones
-- sobre el campo region
SELECT * FROM TblClientes
WHERE region='Ya no es NULL'
GO
-- Verificando en la nueva tabla todos los
-- clientes que han sido actualizados en el
-- campo region(NULL)
SELECT * FROM TmpPrueba
GO
para
la
que
se
solicita
Valor_Retorno
Significado
0
-1
-2
-3
Monitorizar los cursores Transact-SQL
Transact-SQL proporciona dos variables globales
y una funcin que le ayudara a comprender que
esta
sucediendo
con
sus
cursores
@@CURSOR_ROWS devuelve el numero de filas
del ultimo cursor abierto en la conexin.
Valor_Retorno
Significado
-m
El cursor aun no se ha
terminado de poblar; existen
actualmente m filas en el
conjunto de cursor
El cursor es dinmico y el
numero de filas puede cambiar
O no se ha abierto ningn
cursor, o se ha cerrado o
liberado
el
ultimo
cursor
abierto, o el cursor no contiene
ninguna fila.
El numero de filas es n
-1
0
Significado
-1
-2
Ejemplo:
USE NorthWind
GO
DECLARE cursorsimple CURSOR
LOCAL STATIC
FOR
SELECT CompanyName FROM Customers
WHERE Region IS NOT NULL
OPEN cursorsimple
-- Muestar el Nro de filas
SELECT @@CURSOR_ROWS
AS 'FilasCursor(@@CURSOR_ROWS)'
-- Obtiene la primera fila
FETCH cursorsimple
-- Muestra los resultados de la ltima lectura
SELECT @@FETCH_STATUS
AS 'EstadoFETCH(@@FETCH_STATUS)'
-- Comprueba el estado del cursor
SELECT CURSOR_STATUS('local','cursorsimple')
AS 'EstadoCursor(CURSOR_STATUS)'
-- Obtiene la ltima fila
FETCH LAST FROM cursorsimple
-- Cerramos el Cursor
CLOSE cursorsimple
-- Cursor o variable Cursor Cerradas
SELECT CURSOR_STATUS('local','cursorsimple')
AS 'EstadoCursor(CURSOR_STATUS)'
-- Liberamos el Cursor
DEALLOCATE cursorsimple
-- Cursor o variable Cursor No Existen
SELECT CURSOR_STATUS('local','cursorsimple')
AS 'EstadoCursor(CURSOR_STATUS)'
GO