CURSORES
Un cursor es una estructura de datos creada en memoria RAM producto de una sentencia SELECT y que nos permite navegar dentro de las filas para obtener la información.
Cada cursor contiene las siguientes 5 partes:
- Declarar cursor: en esta parte declaramos variables y devolvemos un conjunto de valores.
- Abrir el cursor: Esta es la parte inicial del cursor.
- Recuperar los datos: se utiliza para recuperar los datos fila por fila desde un cursor.
- Cerrar el cursor: Esta es una parte de salida del cursor y se usa para cerrar un cursor.
- Desalojar: en esta parte eliminamos la definición del cursor y liberamos todos los recursos del sistema (memoria) asociados con el cursor.
use northwind
go
–Declarando el cursor
Declare Cursor1 Cursor scroll
for select * from dbo.customers
–Abrir el cursor
Open Cursor1
–Navegar
Fetch first from Cursor1
–cerrar el cursor
Close Cursor1
–liberar de memoria
Deallocate Cursor1
|
Sintaxis
DECLARE <Nombre_Cursor> CURSOR [ LOCAL | GLOBAL ]
[ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
[ TYPE_WARNING ]
FOR <Declaración_Select>
[ FOR UPDATE [ OF <Nombre_Columna>[ ,…n ] ] ] [;]
Alcance del cursor
Microsoft SQL Server admite las palabras clave GLOBAL y LOCAL en la instrucción DECLARE CURSOR para definir el alcance del nombre del cursor.
- GLOBAL: especifica que el cursor es global para la conexión, es decir se puede usar en cualquier momento y por cualquier procedimiento, trigger, función o consulta en la sesión .
- LOCAL: especifica que el cursor es local para el Procedimiento almacenado, el desencadenador o la consulta que contiene el cursor.
Opción de recuperación de datos en cursores
Microsoft SQL Server admite las siguientes dos opciones de recuperación de datos:
- FORWARD_ONLY: especifica que el cursor solo se puede desplazar desde la primera hasta la última fila.
- SCROLL: proporciona 6 opciones para obtener los datos (FIRST, LAST, PRIOR, NEXT, RELATIVE y ABSOLUTE).
Tipos de cursores
Microsoft SQL Server admite los siguientes 4 tipos de cursores.
- STATIC
Un cursor estático llena el conjunto de resultados durante la creación del cursor y el resultado de la consulta se almacena en caché durante la vida útil del cursor. Un cursor estático puede moverse hacia adelante y hacia atrás.
- FAST_FORWARD
Este es el tipo de cursor predeterminado. Es idéntico al estático, excepto que solo puede desplazarse hacia adelante.
- DINAMIC
En un cursor dinámico, las adiciones y eliminaciones son visibles para otros en la fuente de datos mientras el cursor está abierto.
- KEYSET
Esto es similar a un cursor dinámico, excepto que no podemos ver registros que otros agreguen. Si otro usuario elimina un registro, es inaccesible desde nuestro conjunto de registros.
Tipos de Bloqueo
El bloqueo es el proceso por el cual un DBMS restringe el acceso a una fila en un entorno multiusuario. Cuando una fila o columna se bloquea exclusivamente, otros usuarios no pueden acceder a los datos bloqueados hasta que se libere el bloqueo. Se utiliza para la integridad de los datos. Esto garantiza que dos usuarios no puedan actualizar simultáneamente la misma columna en una fila.
Microsoft SQL Server admite los siguientes tres tipos de bloqueos.
- READ_ONLY
Especifica que el cursor no se puede actualizar.
- SCROLL_LOCKS
Proporciona integridad de datos en el cursor. Especifica que el cursor bloqueará las filas a medida que se leen en el cursor para garantizar que las actualizaciones o eliminaciones realizadas con el cursor tengan éxito.
- OPTIMISTIC
Especifica que el cursor no bloquea las filas a medida que se leen en el cursor. Por lo tanto, las actualizaciones o eliminaciones realizadas con el cursor no tendrán éxito si la fila se ha actualizado fuera del cursor.
— Declaración del cursor
DECLARE [NOMBRE CURSOR] CURSOR [ LOCAL | GLOBAL ]
[ FORWARD_ONLY | SCROLL ]
FOR [SENTENCIA DE SQL (SELECT)]
— Apertura del cursor
OPEN [NOMBRE CURSOR]
— Lectura de la primera fila del cursor
FETCH [NOMBRE CURSOR] INTO [LISTA DE VARIABLES DECLARADAS]
WHILE (@@FETCH_STATUS = 0)
BEGIN
— Lectura de la siguiente fila de un
cursor
FETCH [NOMBRE CURSOR] INTO [LISTA DE VARIABLES DECLARADAS]
…
— Fin del bucle WHILE
END
— Cierra el cursor
CLOSE [NOMBRE CURSOR]
— Libera los recursos del cursor
DEALLOCATE [NOMBRE CURSOR]
|
El siguiente ejemplo muestra un ejemplo de cursor usando la base de datos northwind.
—-Ejemplo 2
Cursores
Declare @codigo varchar(5),
@compania varchar(200),
@contacto varchar(150),
@pais varchar(100)
Declare ccustomers cursor GLOBAL
for Select customerid, companyname, contactname
, country from customers
Open ccustomers
fetch ccustomers into @codigo, @compania, @contacto,
@pais
while(@@fetch_status=0)
begin
print @codigo +‘ ‘+ @compania +‘ ‘+ @contacto +‘ ‘+@pais
fetch ccustomers into @codigo, @compania, @contacto,
@pais
end
close ccustomers
deallocate ccustomers
GO
|
Cuando trabajamos con cursores, la función @@FETCH_STATUS nos indica el estado de la última instrucción
FETCH emitida, los valores posibles son:
Valor devuelto
|
Descripción
|
0
|
La instrucción FETCH se ejecutó correctamente.
|
-1
|
La instrucción FETCH no se ejecutó correctamente o la fila estaba más
allá del conjunto de resultados.
|
-2
|
Falta la fila recuperada.
|
|
|
Para actualizar los datos de un cursor debemos especificar FOR UPDATE después de la sentencia SELECT en la declaración del cursor, y WHERE CURRENT OF [Nombre Cursor] en la sentencia UPDATE tal y como muestra el siguiente ejemplo.
—-Ejemplo 3
Cursores Actualizar datos
Declare @codigo
varchar(5),
@compania varchar(200),
@contacto varchar(150),
@pais varchar(100)
Declare ccustomers
cursor GLOBAL
for Select
customerid,
companyname,
contactname
, country
from customers
FOR UPDATE
Open ccustomers
fetch ccustomers
into @codigo, @compania, @contacto,
@pais
while(@@fetch_status=0)
begin
UPDATE customers
set companyname
= @compania
+ ‘(Modificado)’
where current of ccustomers
fetch ccustomers
into @codigo, @compania, @contacto,
@pais
end
close ccustomers
deallocate ccustomers
go
|
En la apertura del cursor, podemos especificar los siguientes parámetros:
<nombre_cursor> CURSOR [ LOCAL | GLOBAL ]
[ FORWARD_ONLY |
SCROLL ][ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
[ TYPE_WARNING ]
FOR Sentencia_sql
|
|
Muy bien explicado, gracias!