jueves, 26 de noviembre de 2009 a las 10:27hs por Dario Krapp
Introducción, conceptos y definiciones básicas
Los cursores en SQL Server pueden definirse como un elemento que representará a un conjunto de datos determinado por una consulta T-SQL. Los cursores permiten recorrer fila a fila, leer y eventualmente modificar dicho conjunto de resultados.
Existe una amplia variedad de opciones y de funciones para crear y operar sobre cursores en SQL Server. En este artículo, donde hemos utilizado SQL Server 2008 Enterprise Edition para los ejemplos, damos un paseo por las posibilidades disponibles.
La creación y utilización de un cursor estará compuesta, como es de esperarse, por una serie de instrucciones T-SQL, las cuales podrán separarse en grupos bien diferenciados. Estos son: Declaración, Apertura, Acceso a datos, Cierre y Desalojo. A continuación detallamos cada grupo de instrucciones.
Declaración
El primer paso constará de la declaración del cursor, donde se indicarán (junto con el nombre del cursor) la consulta que el mismo representará y algunas otras características bastante interesantes.
Un ejemplo de declaración de cursor es el siguiente:
DECLARE ProdInfo CURSOR FOR SELECT Name FROM Production.Product
Donde ProdInfo representa el nombre del cursor y la sentencia “SELECT ProductNumber,Name FROM Production.Product” es el conjunto de datos del mismo.
Como comentamos previamente, en este paso es posible definir algunas características del comportamiento del cursor, por ejemplo la sentencia:
DECLARE ProdInfo CURSOR READ_ONLY FOR SELECT Name FROM Production.Product
Indica que el cursor será de solo lectura. Más adelante veremos en detalle las opciones disponibles, por el momento nuestro objetivo es crear un cursor lo más simple posible.
Apertura
La apertura del cursor ejecutará la consulta definida en el paso previo y cargará los datos en el mismo. La función OPEN de T-SQL permite efectuar esta terea. Para continuar con el ejemplo previo, la forma de abrir el cursor será la siguiente:
OPEN ProdInfo
Recorrido del cursor y acceso a los datos
Este paso consta de recorrer los resultados del cursor. La instrucción FETCH permite efectuar dicha operación. Las filas leídas podrán copiarse a variables utilizando la sentencia INTO en combinación con la sentencia FETCH, por ejemplo:
FETCH NEXT FROM ProdInfo INTO @Description
Esta sentencia toma la siguiente fila de resultados del cursor y lo aloja en la variable @Description.
Un detalle a comentar es que en la sentencia INTO (como puede verse en el ejemplo anterior) el mapeo entre columnas del cursor y variables se realiza implícitamente, asignándose la primera columna a la primera variable, la segunda columna a la segunda variable y así sucesivamente. Esto implica que deberán crearse tantas variables como columnas se definan en la declaración del cursor y las mismas deberán ubicarse en el mismo orden que se encuentran definidas las columnas en la sentencia SELECT de la declaración.
Como cada sentencia FETCH leerá un registro, una pregunta interesante que podríamos hacernos es, ¿de qué manera podremos saber si existe un próximo o previo registro, o si hemos llegado al límite (ya sea superior o inferior)?. La respuesta se encontrará en una variable de SQL Server llamada @@FETCH_STATUS que tomará el valor 0 si la lectura del registro ha sido correcta.
En este punto será también posible modificar o eliminar las filas que se van recorriendo, como veremos al final del artículo.
Cierre del cursor
En el cierre del cursor se liberarán los registros tomados por el mismo. Una vez que el cursor es cerrado ya no podrá recorrerse el conjunto de resultados hasta que el mismo sea reabierto, la sentencia CLOSE cerrará un cursor abierto y la sintaxis puede verse a continuación:
CLOSE ProdInfo
Desalojo del cursor
Este paso eliminará la referencia al cursor definido previamente, por lo que ya no será posible realizar una reapertura del mismo, en este caso la sintaxis será:
DEALLOCATE ProdInfo
Ejemplo de cursor
A continuación juntaremos todos los pasos descriptos previamente y crearemos el ejemplo más simple de un cursor el cual recorrerá la tabla Production.ProductDescription de la base de datos AdventureWorks y mostrará por pantalla el valor del registro Description luego que el mismo ha sido copiado a la variable @Description.
DECLARE @Description AS nvarchar(400) DECLARE ProdInfo CURSOR FOR SELECT [Description] FROM Production.ProductDescription OPEN ProdInfo FETCH NEXT FROM ProdInfo INTO @Description WHILE @@fetch_status = 0 BEGIN PRINT @Description FETCH NEXT FROM ProdInfo INTO @Description END CLOSE ProdInfo DEALLOCATE ProdInfo
En el ejemplo puede verse la utilización de la variable @@FETCH_STATUS para verificar la existencia de la fila leída, por otra parte la sentencia FETCH NEXT devolverá la próxima fila de datos, siempre que la misma exista.
Este ejemplo, a pesar de parecer tan trivial y claro esconde un amplia variedad de comportamientos que el cursor asumirá, y que en este caso han tomado el valor por defecto, ya que no los hemos definido explícitamente.
El próximo paso será dar una recorrida por estas opciones y entender cuales se adaptarán mejor a nuestras necesidades.
Categoria SQL Server | Etiquetas: Cursor, SQL Server
Claro y sencillo… me ayudo.
Una buena iniciación al uso de los cursores en Transact SQL, buen aporte.
Excelente esta muy entendible, gracias por el aporte, pero desearia obtener mas info tal vez me podrian ayudar con un manual. O donde puedo conseguir
Hola Kristian, muchas gracias.
Podés encontrar algo de informacion teórica y práctica en esta url
http://msdn.microsoft.com/fr-fr/library/ms191179.aspx
slds
muy buen aporte
Practico y concreto, buen aporte.
Excelente!! mas claro lo tengo
En que parte se guardan los cursores, tengo sql server 2008 y no encuentro en el explorador de objetos el cursor creado.
Hola jeremiasm, buenos días
El tema es que un cursor no es un objeto persistente que se almacena en tablas del SQL como por ejemplo las tablas, los stored procedures o los indices entre otros.
Los cursores son objetos que se crean en memoria (por eso es importante utilizar la sentencia deallocate para desalojarlo de la memoria que utiliza SQL Server). Por ese motivo no los vas a poder encontrar en el object explorer.
Slds
entendi muy bien, se agradece
Gracias Por la Ayuda …
Buen Aporte .
Gracias por el aporte, por cierto que buen nombre el del sitio, me veo muy identificado con este!.
Muy buen comentario , quisiera me pudieran ayudar , quiero realizar un cursor haciendo lo siguiente espero me puedan ayudar tengo 2 tablas
Tabla 1 Folio
Tabla 2 Folio + Precio
quisiera actualizar mi tabla 1 de la 2 por medio de un cursor,quedo en espera de sus valiosos comentarios
excelente me gusto
Tremendo!!
Muchas gracias!!!
muy bueno, pero quisiera que me puedas ayudar, quiero hacer un cursor que me ayude a actualizar un campo por ejemplo:
telefono DNI1
telefono DNI1
de lo anterior quisiera lo siguiente:
telefono1 DNI1
telefono2 DNI1
Tendras algun material que me pueda ayudar.
Saludos
Buenas tardes.
No se entiende bien tu ejemplo, podrás darnos un poco más de información?
Saludos.
Muy Buen Aporte,, lo voy a revisar, mas tarde (a la media noche), pero por lo que leí se nota claro y sencillo.
Hola a todos, tengo dos tablas ( Empleados y Entradas ), lo que quiero saber es como le hago para que la consulta me devuelva lo siguiente:
No. Nombre Reg1 Reg2 Reg3 Reg4
01 Pedro 07:10:20 11:45:00 12:36:14 18:50:44
02 Luis 09:15:20 11:05:00 11:36:14 17:50:44
La Tabla Empleado tienen los siguientes Campos;
No. int
Nombre varchar
Registros de la tabla de Empleados
01 Pedro
02 Luis
03 Paco
Y la Tabla Entradas
No. int
Fecha date
Registro time(0)
Registros de la tabla Entradas
01 2015-01-01 07:10:20
02 2015-01-01 09:15:20
01 2015-01-01 11:45:00
02 2015-01-01 11:05:00
01 2015-01-01 12:36:14
02 2015-01-01 11:36:14
01 2015-01-01 18:50:44
02 2015-01-01 17:50:44
Realmente muy útil!
Muy bien explicado, excelente (y)
gracias por el aporte, me ha servido como no tienes idea.
saludos
Muchas gracias! Mas claro imposible!!!
Muchas Gracias, es muy util esta información.
Pero tengo una duda, cree un cursor dentro de un procedimiento almacenado para hacer mas sencilla su ejecución, al ejecutarlo por primera vez no hay problema funciona bien, pero si lo ejecuto por segunda vez no me regresa nada, tengo que esperar para volverlo a ejecutar, a pesar de que tengo el «Dellocate» y el «Close», ¿Alguna idea de que pudiera pasar?
Oye, muchas gracias por compartir esta información tan importante de una manera tan clara.
Muy buena explicación!!! Clara y sencilla
Hola Dario. Primero gracias por su ayuda.
Como puedo hacer en el uso de cursores para ver los resultados del proceso de cada registro del cursor. He notado que cuando utilizo cursores los resultados solo se muestran al finalizar el proceso completo del cursor.
Saludos.
Nuevamente GRACIAS.
Buenísima explicación!!! Me sirvió bastante!
Como llamo a un cursor dentro de un store
Se puede declarar un cursor con la base de datos pasada como parámetro al sp????
El dia que quiten esta pagina me quedo sin cursores, tengo como 5 años copiando y pegando el codigo jajajajaja
Buenísimo, nos alegramos que te sirva!!!!!
muy bueno, y muy bien escrito.
Muy bueno amigo mio, he revisado este post dos veces y las dos ocasiones me ha servido de mucho. Muchas gracias por el aporte.
Gracias por el aporte, estoy empezando en el uso de cursores
tengo dudaa
se puede hacer esto??? el cursor puede guardar mas parametros?
Podés traer más de un campo, pero entonces deberías declarar una variable por cada campo, algo así:
¡Suerte!
muy bueno ,siempre ocupe este ejemplo para mis cursores. Gracias
¡Que pro!
Gracias totales la pagina tiene articulos muy interesantes!
Excelente y al Grano.
Muy conciso…gracias
Excelente explicación, gracias por el aporte.
Excelente, me ha servido en el trabajo.
Muchas gracias. Muy clarito el uso de los cursores.
Pero a mí me está dando un error cerca de FOR.
Hola Chema.
¿Cuál es el error que te devuelve el SQL? ¿Podrías copiar el query completo?
Gracias.
Creo que la variable del cursor debe ir sin la «@». Seria «DECLARE varCursor CURSOR FOR SELECT …»