- Declarar el cursor, utilizando DECLARE
- Abrir el cursor, utilizando OPEN
- Leer los datos del cursor, utilizando FETCH ... INTO
- Cerrar el cursor, utilizando CLOSE
- Liberar el cursor, utilizando DEALLOCATE
La sintaxis general para trabajar con un cursor es la siguiente.
DECLARE nombre_cursor CURSOR FOR sentencia_sql; -- apertura del cursor OPEN nombre_cursor; -- Lectura de la primera fila del cursor FETCH nombre_cursor; INTO lista_variables; WHILE (@@FETCH_STATUS = 0) BEGIN-- Lectura de la siguiente fila de un cursorEND -- Fin del bucle WHILE -- Cierra el cursor CLOSE nombre_cursor; -- Libera los recursos del cursorDEALLOCATE <nombre_cursor> |
DECLARE @Id int, @Nombre varchar(255), @Apellido1 varchar(255), @Apellido2 varchar(255), @NifCif varchar(20), @FxNacimiento datetime -- Declaración del cursor DECLARE cClientes CURSOR FOR SELECT Id, Nombre, Apellido1, Apellido2, NifCif, FxNacimiento FROM CLIENTES -- Apertura del cursorOPEN cClientes -- Lectura de la primera fila del cursor FETCH cClientes INTO @id, @Nombre, @Apellido1, @Apellido2, @NifCif, @FxNacimiento WHILE (@@FETCH_STATUS = 0 ) BEGINPRINT @Nombre + ' ' + @Apellido1 + ' ' + @Apellido2END -- Cierre del cursor CLOSE cClientes -- Liberar los recursos
|
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. |
|
- LOCAL
Especifica que el ámbito del cursor es local para el proceso por lotes, procedimiento almacenado o desencadenador en que se creó el cursor.
DECLARE cClientes CURSOR LOCAL FOR SELECT Id, Nombre, Apellido1, Apellido2, NifCif, FxNacimiento FROM CLIENTES |
- GLOBAL
Especifica que el ámbito del cursor es global para la conexión. Puede hacerse referencia al nombre del cursor en cualquier procedimiento almacenado o proceso por lotes que se ejecute en la conexión.
DECLARE cClientes CURSOR GLOBAL FOR SELECT Id, Nombre, Apellido1, Apellido2, NifCif, FxNacimiento FROM CLIENTES |
El siguiente conjunto de parámetros que podemos especificar es [ FORWARD_ONLY | SCROLL ]. A continuación mostramos el significado de cada una de estas opciones.
- FORWARD_ONLY
Especifica que el cursor sólo se puede desplazar de la primera a la última fila. FETCH NEXT es la única opción de recuperación admitida.
DECLARE cClientes CURSOR FORWARD_ONLY FOR SELECT Id, Nombre, Apellido1, Apellido2, NifCif, FxNacimiento FROM CLIENTES |
- SCROLL
Especifica que están disponibles todas las opciones de recuperación (FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE). Si no se especifica SCROLL en una instrucción DECLARE CURSOR la única opción de recuperación que se admite es NEXT. No es posible especificar SCROLL si se incluye también FAST_FORWARD.
Si se incluye la opción SCROLL, la forma en la realizamos la lectura del cursor varia, debiendo utilizar la siguiente sintaxis: FETCH [ NEXT | PRIOR | FIRST | LAST | RELATIVE | ABSOLUTE ] FROM <>
-- Declaracion de variables para el cursorDECLARE @Id int, @Nombre varchar(255), @Apellido1 varchar(255), @Apellido2 varchar(255), @NifCif varchar(20), @FxNacimiento datetime -- Declaración del cursor DECLARE cClientes CURSOR SCROLL FOR SELECT Id, Nombre, Apellido1, Apellido2, NifCif, FxNacimiento FROM CLIENTES -- Apertura del cursorOPEN cClientes -- Lectura de la primera fila del cursorFETCH NEXT FROM cClientes INTO @id, @Nombre, @Apellido1, @Apellido2, @NifCif, @FxNacimiento WHILE (@@FETCH_STATUS = 0 ) BEGINPRINT @Nombre + ' ' + @Apellido1 + ' ' + @Apellido2END -- Lectura de la fila anterior FETCH PRIOR FROM cClientes INTO @id, @Nombre, @Apellido1, @Apellido2, @NifCif, @FxNacimiento PRINT @Nombre + ' ' + @Apellido1 + ' ' + @Apellido2 -- Cierre del cursorCLOSE cClientes -- Liberar los recursosDEALLOCATE cClientes |
- STATIC
Define un cursor que hace una copia temporal de los datos que va a utilizar. Todas las solicitudes que se realizan al cursor se responden desde esta tabla temporal de tempdb; por tanto, las modificaciones realizadas en las tablas base no se reflejan en los datos devueltos por las operaciones de recuperación realizadas en el cursor y además este cursor no admite modificaciones.
DECLARE cClientes CURSOR STATIC FOR SELECT Id, Nombre, Apellido1, Apellido2, NifCif, FxNacimiento FROM CLIENTES |
- KEYSET
Especifica que la pertenencia y el orden de las filas del cursor se fijan cuando se abre el cursor. El conjunto de claves que identifica las filas de forma única está integrado en la tabla denominada keyset de tempdb.
DECLARE cClientes CURSOR KEYSET FOR SELECT Id, Nombre, Apellido1, Apellido2, NifCif, FxNacimiento FROM CLIENTES |
- DYNAMIC
Define un cursor que, al desplazarse por él, refleja en su conjunto de resultados todos los cambios realizados en los datos de las filas. Los valores de los datos, el orden y la pertenencia de las filas pueden cambiar en cada operación de recuperación. La opción de recuperación ABSOLUTE no se puede utilizar en los cursores dinámicos.
DECLARE cClientes CURSOR DYNAMIC FOR SELECT Id, Nombre, Apellido1, Apellido2, NifCif, FxNacimiento FROM CLIENTES |
- FAST_FORWARD
Especifica un cursor FORWARD_ONLY, READ_ONLY con las optimizaciones de rendimiento habilitadas. No se puede especificar FAST_FORWARD si se especifica también SCROLL o FOR_UPDATE.
DECLARE cClientes CURSOR FAST_FORWARD FOR SELECT Id, Nombre, Apellido1, Apellido2, NifCif, FxNacimiento FROM CLIENTES |
El siguiente conjunto de parámetros que podemos especificar es [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]. A continuación mostramos el significado de cada una de estas opciones.
- READ_ONLY
Evita que se efectúen actualizaciones a través de este cursor. No es posible hacer referencia al cursor en una cláusula WHERE CURRENT OF de una instrucción UPDATE o DELETE. Esta opción reemplaza la capacidad de actualizar el cursor.
DECLARE cClientes CURSOR READ_ONLY FOR SELECT Id, Nombre, Apellido1, Apellido2, NifCif, FxNacimiento FROM CLIENTES |
- SCROLL_LOCKSEspecifica que se garantiza que las actualizaciones o eliminaciones posicionadas realizadas a través del cursor serán correctas. Microsoft SQL Server bloquea las filas cuando se leen en el cursor para garantizar que estarán disponibles para futuras modificaciones. No es posible especificar SCROLL_LOCKS si se especifica también FAST_FORWARD o STATIC.
DECLARE cClientes CURSOR SCROLL_LOCKS FOR SELECT Id, Nombre, Apellido1, Apellido2, NifCif, FxNacimiento FROM CLIENTES |
- OPTIMISTIC
Especifica que las actualizaciones o eliminaciones posicionadas realizadas a través del cursor no se realizarán correctamente si la fila se ha actualizado después de ser leída en el cursor. SQL Server no bloquea las filas al leerlas en el cursor. En su lugar, utiliza comparaciones de valores de columna timestamp o un valor de suma de comprobación si la tabla no tiene columnas timestamp, para determinar si la fila se ha modificado después de leerla en el cursor. Si la fila se ha modificado, el intento de actualización o eliminación posicionada genera un error. No es posible especificar OPTIMISTIC si se especifica también FAST_FORWARD.
DECLARE cClientes CURSOR OPTIMISTIC FOR SELECT Id, Nombre, Apellido1, Apellido2, NifCif, FxNacimiento FROM CLIENTES |
- TYPE_WARNINGEspecifica que se envía un mensaje de advertencia al cliente si el cursor se convierte implícitamente del tipo solicitado a otro.
DECLARE cClientes CURSOR TYPE_WARNING FOR SELECT Id, Nombre, Apellido1, Apellido2, NifCif, FxNacimiento FROM CLIENTES |
DECLARE cClientes CURSOR LOCAL STATIC TYPE_WARNING FOR SELECT Id, Nombre, Apellido1, Apellido2, NifCif, FxNacimiento FROM CLIENTES |
-- Declaracion de variables para el cursorDECLARE @Id int, @Nombre varchar(255), @Apellido1 varchar(255), @Apellido2 varchar(255), @NifCif varchar(20), @FxNacimiento datetime -- Declaración del cursorDECLARE cClientes CURSOR FOR SELECT Id, Nombre, Apellido1, Apellido2, NifCif, FxNacimiento FROM CLIENTES FOR UPDATE -- Apertura del cursorOPEN cClientes -- Lectura de la primera fila del cursorFETCH cClientes INTO @id, @Nombre, @Apellido1, @Apellido2, @NifCif, @FxNacimiento WHILE (@@FETCH_STATUS = 0 ) BEGINUPDATE ClientesEND -- Cierre del cursor CLOSE cClientes -- Liberar los recursos
|
Hugo Román Bernachea
Twitter: @bernachea
5 comentarios:
hola quisiera q me clobaores con un cursor en sql que sitva para migrar los datos de una hoja de excel a un tabla sql medaiante un cursor
gracias
andresx421@hotmail.com
Excelente tema, solo hay que agregar que el uso de CURSORES en SQL Server, no es RECOMENDADO, ya que estos, afectan de forma significativa el tiempo de respuesta del servidor de datos, ya que estos, los cursores, son creados en memoria y muchas de las cosas que se hacen con cursores, se pueden hacer con T-SQL como CTE o tablas temporales. Saludos.
NO UTILICEN CURSORES NUNCA,
T-SQL tiene todo lo necesario para evitar su uso
es cierto nunca usen cursores baja de forma significativa el rendimiento se optimiza mas usando tablas temporales
Hay consultas que sólo se podrán resolver con cursores, sólo resta saber cuáles.
Publicar un comentario