Usando cursor en SQL Server

Usando Cursores en SQL Server

Los cursores permiten almacenar los datos de una consulta T-SQL en memoria y poder manipular los datos de los elementos resultantes para realizar operaciones con ellos. Se recomienda su uso con cierto cuidado porque consume mucha memoria, la instrucción select que llena el cursor debe ser lo más selectiva posible.

Proceso para declarar, abrir, usar, cerrar y liberar los datos de un cursor

  1. Declarar el cursor, utilizando DECLARE Cursor
  2. Abrir el cursor, utilizando OPEN
  3. Leer los datos del cursor, utilizando FETCH … INTO dentro de una estructura While
  4. Cerrar el cursor, utilizando CLOSE
  5. Liberar el cursor, utilizando DEALLOCATE

Para mas información ver
Cursores en SQL Server
Cursores con variables tipo tabla
Cursores en Store procedures
Fetch Next en Select
Crear tablas
Insertar registros
Variables tipo tabla
Unión en Select

En este artículo se muestra como usar un cursor, el ejemplo es con una tabla de Alumnos, tiene registrado el código, su nombre y cinco calificaciones, se pretende hacer un reporte de estas en columnas adicionales a la tabla ordenando las calificaciones de menor a mayor.

Usando la base de datos Northwind

use Northwind
go

La tabla de alumnos y la inserción de los registros para el ejercicio.

Create table Alumnos
(
AlumnosCodigo nchar(4),
AlumnosNombre nvarchar(50),
AlumnosNota1 int,
AlumnosNota2 int,
AlumnosNota3 int,
AlumnosNota4 int,
AlumnosNota5 int
constraint AlumnosPK primary key (AlumnosCodigo)
)
go

Insert into Alumnos
Values (‘0001′,’Fernando Luque’,18,5,12,8,13),
(‘0002′,’Fagos’,9,15,12,7,13),
(‘0003′,’Vania’,20,6,15,18,14),
(‘0004′,’Lucas’,18,15,2,8,17),
(‘0005′,’Pedro’,4,5,20,18,13)
go

El listado de los alumnos
select * from Alumnos
go
El resultado se muestra en la siguiente imagen.

El cursor para obtener el resultado es el siguiente

Declare cursorAlumnos cursor for
select * from Alumnos
Open cursorAlumnos
Declare @Resultados Table
(
Codigo nchar(4),
Nombre nvarchar(50),
Nota1 int,
Nota2 int,
Nota3 int,
Nota4 int,
Nota5 int,
Primero int,
Segundo int,
Tercero int,
Cuarto int,
Quinto int
)
— Variables para los datos leídos del cursor.
Declare @Codigo nchar(4), @Nombre nvarchar(50), @Nota1 int, @Nota2 int, @Nota3 int, @Nota4 int, @Nota5 int
Fetch cursorAlumnos into @Codigo , @Nombre , @Nota1 , @Nota2 , @Nota3 , @Nota4 , @Nota5
— Recorrer el cursor
while (@@FETCH_STATUS = 0)
Begin
Declare @Valor1 int, @Valor2 int, @Valor3 int, @Valor4 int, @Valor5 int
Declare @NotasOrdenadas Table
(
Orden int ,N int
)
Insert into @NotasOrdenadas
select 1,AlumnosNota1 from Alumnos where AlumnosCodigo = @Codigo
union
select 2, AlumnosNota2 from Alumnos where AlumnosCodigo = @Codigo
union
select 3, AlumnosNota3 from Alumnos where AlumnosCodigo = @Codigo
union
select 4, AlumnosNota4 from Alumnos where AlumnosCodigo = @Codigo
union
select 5, AlumnosNota5 from Alumnos where AlumnosCodigo = @Codigo
Set @Valor1 = ( select top 1 n from @NotasOrdenadas order by N asc)
Set @Valor2 = ( select n from @NotasOrdenadas order by N asc offset 1 rows fetch next 1 rows only)
Set @Valor3 = ( select n from @NotasOrdenadas order by N asc offset 2 rows fetch next 1 rows only)
Set @Valor4 = ( select n from @NotasOrdenadas order by N asc offset 3 rows fetch next 1 rows only)
Set @Valor5 = ( select n from @NotasOrdenadas order by N asc offset 4 rows fetch next 1 rows only)
delete @NotasOrdenadas
— select @Valor1, @Valor2, @Valor3, @Valor4, @Valor5
insert into @Resultados values
(@Codigo , @Nombre , @Nota1 , @Nota2 , @Nota3 , @Nota4 , @Nota5,
@Valor1, @Valor2, @Valor3, @Valor4, @Valor5)
Fetch cursorAlumnos into @Codigo , @Nombre , @Nota1 , @Nota2 , @Nota3 , @Nota4 , @Nota5
End
Close cursorAlumnos
Deallocate cursorAlumnos
select * from @Resultados
go
El resultado se muestra en la siguiente imagen.

Note el reporte del cursor, el alumno con código 0001 tiene 5 notas, estas calificaciones son: Nota1: 18, Nota2: 5, Nota3: 12, Nota4: 8 y Nota5: 13, el cursor añade al reporte cinco columnas adicionales con las notas ordenadas de menor a mayor.