| 
   
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!