Você está na página 1de 12

Qu son y cmo se construyen los cursores en SQL.

En algunos SGDB es posible la abertura de cursores de datos desde el propio entorno de trabajo, para ello se utilizan, normalmente procedimientos almacenados. La sintaxis para definir un cursor es la siguiente: DECLARE nombre-cursor FOR especificacion-consulta [ORDER BY] Por ejemplo: DECLARE Mi_Cursor FOR SELECT num_emp, nombre, puesto, salario FROM empleados WHERE num_dept = 'informatica' Este comando es meramente declarativo, simplemente especifica las filas y columnas que se van a recuperar. La consulta se ejecuta cuando se abre o se activa el cursor. La clusula [ORDER BY] es opcional y especifica una ordenacin para las filas del cursor; si no se especifica, la ordenacin de las filas es definida el gestor de SGBD. Para abrir o activar un cursor se utiliza el comando OPEN del SQL, la sintaxis en la siguiente: OPEN nombre-cursor [USING lista-variables] Al abrir el cursor se evala la consulta que aparece en su definicin, utilizando los valores actuales de cualquier parmetro referenciado en la consulta, para producir una coleccin de filas. El puntero se posiciona delante de la primera fila de datos (registro actual), esta sentencia no recupera ninguna fila. Una vez abierto el cursos se utiliza la clusula FETCH para recuperar las filas del cursor, la sintaxis es la siguiente: FETCH nombre-cursor INTO lista-variables Lista - variables son las variables que van a contener los datos recuperados de la fila del cursor, en la definicin deben ir separadas por comas. En la lista de variables se deben definir tantas variables como columnas tenga la fila a recuperar.

Para cerrar un cursor se utiliza el comando CLOSE, este comando hace desaparecer el puntero sobre el registro actual. La sintaxis es: CLOSE nombre-cursor Por ltimo, y para eliminar el cursor se utiliza el comando DROP CURSOR. Su sintaxis es la siguiente: DROP CURSOR nombre-cursor Ejemplo (sobre SQL-SERVER): Abrir un cursor y recorrelo DECLARE Employee_Cursor CURSOR FOR SELECT LastName, FirstName FROM Northwind.dbo.Employees WHERE LastName like 'B%' OPEN Employee_Cursor FETCH NEXT FROM Employee_Cursor WHILE @@FETCH_STATUS = 0 BEGIN FETCH NEXT FROM Employee_Cursor END CLOSE Employee_Cursor DEALLOCATE Employee_Cursor Abrir un cursor e imprimir su contenido SET NOCOUNT ON DECLARE @au_id varchar(11), @au_fname varchar(20), @au_lname varchar(40), @message varchar(80), @title varchar(80) PRINT "-------- Utah Authors report --------" DECLARE authors_cursor CURSOR FOR SELECT au_id, au_fname, au_lname FROM authors WHERE state = "UT" ORDER BY au_id

OPEN authors_cursor FETCH NEXT FROM authors_cursor INTO @au_id, @au_fname, @au_lname WHILE @@FETCH_STATUS = 0 BEGIN PRINT " " SELECT @message = "----- Books by Author: " + @au_fname + " " + @au_lname PRINT @message DECLARE titles_cursor CURSOR FOR SELECT t.title FROM titleauthor ta, titles t WHERE ta.title_id = t.title_id AND ta.au_id = au_id OPEN titles_cursor FETCH NEXT FROM titles_cursor INTO @title IF @@FETCH_STATUS <> 0 PRINT " <<No Books>>" WHILE @@FETCH_STATUS = 0 BEGIN SELECT @message = " " + @title PRINT @message FETCH NEXT FROM titles_cursor INTO @title END CLOSE titles_cursor DEALLOCATE titles_cursor FETCH NEXT FROM authors_cursor

INTO @au_id, @au_fname, @au_lname END CLOSE authors_cursor DEALLOCATE authors_cursor GO Recorrer un cursor USE pubs GO DECLARE authors_cursor CURSOR FOR SELECT au_lname FROM authors WHERE au_lname LIKE "B%" ORDER BY au_lname OPEN authors_cursor FETCH NEXT FROM authors_cursor WHILE @@FETCH_STATUS = 0 BEGIN FETCH NEXT FROM authors_cursor END CLOSE authors_cursor DEALLOCATE authors_cursor Recorrer un cursor guardando los valores en variables USE pubs GO DECLARE @au_lname varchar(40) DECLARE @au_fname varchar(20) DECLARE authors_cursor CURSOR FOR SELECTau_lname, au_fname FROM authors WHERE au_lname LIKE "B%" ORDER BY au_lname, au_fname OPEN authors_cursor FETCH NEXT FROM authors_cursor INTO @au_lname, @au_fname WHILE @@FETCH_STATUS = 0 BEGIN PRINT "Author: " + @au_fname + " " + @au_lname FETCH NEXT FROM authors_cursor INTO @au_lname, @au_fname

END CLOSE authors_cursor DEALLOCATE authors_cursor Ejemplo (sobre SQL-SERVER): 'Abrir un cursor y recorrelo DECLARE Employee_Cursor CURSOR FOR SELECT LastName, FirstName FROM Northwind.dbo.Employees WHERE LastName like 'B%' OPEN Employee_Cursor FETCH NEXT FROM Employee_Cursor WHILE @@FETCH_STATUS = 0 BEGIN FETCH NEXT FROM Employee_Cursor END CLOSE Employee_Cursor DEALLOCATE Employee_Cursor EJM: Abrir un cursor e imprimir su contenido USE PUBS GO SET NOCOUNT ON DECLARE @au_id varchar(11), @au_fname varchar(20), @au_lname varchar(40), @message varchar(80),

@title varchar(80) PRINT "-------- Utah Authors report --------" DECLARE authors_cursor CURSOR FOR SELECT au_id, au_fname, au_lname FROM authors WHERE state = "UT" ORDER BY au_id OPEN authors_cursor FETCH NEXT FROM authors_cursor INTO @au_id, @au_fname, @au_lname WHILE @@FETCH_STATUS = 0 BEGIN PRINT " " SELECT @message = "----- Books by Author: " + @au_fname + " " + @au_lname PRINT @message DECLARE titles_cursor CURSOR FOR SELECT t.title FROM titleauthor ta, titles t WHERE ta.title_id = t.title_id AND ta.au_id = au_id OPEN titles_cursor FETCH NEXT FROM titles_cursor INTO @title IF @@FETCH_STATUS <> 0 PRINT " <<No Books>>"

WHILE @@FETCH_STATUS = 0 BEGIN SELECT @message = " " + @title PRINT @message FETCH NEXT FROM titles_cursor INTO @title END CLOSE titles_cursor DEALLOCATE titles_cursor FETCH NEXT FROM authors_cursor INTO @au_id, @au_fname, @au_lname END CLOSE authors_cursor DEALLOCATE authors_cursor GO Ejemplos

A.Uso de cursores simples y su sintaxis


El conjunto de resultados generado al abrir este cursor contiene todas las filas y todas las columnas de la tabla. Este cursor se puede actualizar, y todas las actualizaciones y eliminaciones se representan en las bsquedas realizadas para este cursor. FETCHNEXT es la nica bsqueda disponible porque la opcin SCROLL no se ha especificado.
DECLARE vend_cursor CURSOR FOR SELECT * FROM Purchasing.Vendor OPEN vend_cursor FETCH NEXT FROM vend_cursor;

B.Uso de cursores anidados para elaborar resultados de informes


En el ejemplo siguiente se muestra cmo se pueden anidar los cursores para elaborar informes complejos. El cursor interno se declara para cada proveedor.
SET NOCOUNT ON; DECLARE @vendor_id int, @vendor_name nvarchar(50),

@message varchar(80), @product nvarchar(50); PRINT '-------- Vendor Products Report --------'; DECLARE vendor_cursor CURSOR FOR SELECT VendorID, Name FROM Purchasing.Vendor WHERE PreferredVendorStatus = 1 ORDER BY VendorID; OPEN vendor_cursor FETCH NEXT FROM vendor_cursor INTO @vendor_id, @vendor_name WHILE @@FETCH_STATUS = 0 BEGIN PRINT ' ' SELECT @message = '----- Products From Vendor: ' + @vendor_name PRINT @message -- Declare an inner cursor based -- on vendor_id from the outer cursor. DECLARE product_cursor CURSOR FOR SELECT v.Name FROM Purchasing.ProductVendor pv, Production.Product v WHERE pv.ProductID = v.ProductID AND pv.VendorID = @vendor_id -- Variable value from the outer cursor OPEN product_cursor FETCH NEXT FROM product_cursor INTO @product IF @@FETCH_STATUS <> 0 PRINT ' <<None>>' WHILE @@FETCH_STATUS = 0 BEGIN SELECT @message = ' ' + @product PRINT @message FETCH NEXT FROM product_cursor INTO @product END CLOSE product_cursor DEALLOCATE product_cursor -- Get the next vendor. FETCH NEXT FROM vendor_cursor INTO @vendor_id, @vendor_name END CLOSE vendor_cursor; DEALLOCATE vendor_cursor; /* Este cursor deja las contraseas iguales al nombre de usuario. La tabla Cliente tiene estos tres campos: CliCod, CliUser, CliPass */ -- declaramos las variables declare @cod as int declare @user as varchar(50) declare @pass as varchar(50)

-- declaramos un cursor llamado "CURSORITO". El select debe contener slo los campos a utilizar. declare CURSORITO cursor for select CliCod, CliUser, CliPass from Cliente open CURSORITO -- Avanzamos un registro y cargamos en las variables los valores encontrados en el primer registro fetch next from CURSORITO into @cod, @user, @pass while @@fetch_status = 0 begin update Cliente set CliPass= @user where CliCod=@cod -- Avanzamos otro registro fetch next from CURSORITO into @cod, @rut, @nombres end -- cerramos el cursor close CURSORITO deallocate CURSORITO

CREATE TABLE [dbo].[colores]( [color] [nchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ) ON [PRIMARY]

Y los siguientes datos: rojo amarillo verde azul Ahora, lo que voy a hacer es que me muestren las columnas concatenadas. Para eso necesito un cursor. El cursor es una forma de ir fila por fila para unir luego datos: --Declarar cursor DECLARE color_Cursor CURSOR FOR SELECT color FROM dbo.colores OPEN color_Cursor --Declarar color y la variable que almacena todos los cursores DECLARE @color varchar(30) DECLARE @todoscolores varchar(300) set @todoscolores='' FETCH NEXT FROM color_Cursor into @color WHILE @@FETCH_STATUS <> -1 BEGIN set @todoscolores=@todoscolores+@color FETCH NEXT FROM color_Cursor into @color

END select @todoscolores as Colores --Cerrar cursores CLOSE color_Cursor DEALLOCATE color_Cursor GO El resultado final son los colores concatenados. rojo amarillo verde azul

Manejo de ciclos y cursores en SQL SERVER


En este ejemplo, voy a mostrar cmo crear varios logins de sql server en SQL Server. Voy a usar el T-SQL que no es otra cosa que el lenguaje transact sql de Microsoft. Una extensin del sql. Los nombres son usuario1, usuario2, usuario3, etc, etc. Este cdigo fue probado en SQL Server 2005 y 2008. Tericamente funciona tambin en SQL Server 2000. Estos ejemplo ayuda mucho a entender como pasar variables dentro de sentencias TSQL. El comando execute es la clave del xito para muchos propsitos de T-SQL. Declare @database varchar(8) Set @database=base1 Execute(create database +@database) El comando execute permite manejar variables facilmente dentro de comandos T-SQL. Cmo crear varios logins y usuarios de base de datos sql server utilizando ciclos. Para borrar la lista de logins y usuarios creados anteriormente Para dar permisos de GRANT CREATE ANY DATABASE A TODOS LOS LOGINS

Cmo crear varios logins y usuarios de base de datos sql server utilizando ciclos: Este es un ejemplo bsico de cmo crear varios logins con nombres aleatorios. /*El siguiente ejemplo crea 10 logins de sql server*/ declare @login varchar(10) declare @count int set @count=1 /*Se usa el comando while en ciclos de sql server*/ while @count<=10 BEGIN set @login='login'+CAST(@count as varchar(2)) /*Crea logins*/ EXECUTE ('CREATE LOGIN ' + @login+' WITH PASSWORD =''coso''') EXECUTE ('CREATE USER '+@login)

set @count=@count +1 END /*Para borrar la lista de logins y usuarios creados anteriormente*/ declare @login varchar(10) declare @count int set @count=1 while @count<=10 BEGIN set @login='login'+CAST(@count as varchar(2)) EXECUTE ('drop LOGIN ' + @login) EXECUTE ('drop USER ' + @login) set @count=@count +1 END Para dar permisos de GRANT CREATE ANY DATABASE A TODOS LOS LOGINS Esto es ms complicado. Primero hay que utilizar cursores de sql server. Cursores es una manera de recibir los datos y manipularlos secuencialmente. En este caso vamos a obtener los logins de la base de datos de la vista master.sys.syslogins. Esta vista contiene los logins del sistema. Vamos a guardar en una variable @login cada uno de los cursores. Entonces, lo primero que hay que hacer es usar el DECLARE, para crear el cursos. Es muy parecido a la declaracin de variables. Luego se abre el cursos con OPEN. FETCH NEXT sirve para ir de fila en fila. Con FETCH NEXT vamos a ir cambiando de login. Luego con execute le damos el permiso deseado y le pasamos el login. /*Para dar permisos de GRANT CREATE ANY DATABASE A TODOS LOS LOGINS DE LA BASE DE DATOS SQL SERVER */ DECLARE Login_Cursor CURSOR FOR SELECT name FROM master.sys.syslogins OPEN Login_Cursor DECLARE @login varchar(30) FETCH NEXT FROM Login_Cursor into @login WHILE @@FETCH_STATUS <> -1 BEGIN execute ('grant create any database to '+@login ) --execute ('create user '+@login ) FETCH NEXT FROM Login_Cursor into @login END CLOSE Login_Cursor DEALLOCATE Login_Cursor GO
Ejemplo:

-- seleccionar empleados desde la db northwind, -- pasando la db fuente en una variable use northwind go declare @sql nvarchar(4000) declare @c cursor declare @db_name sysname declare @emp_id char(9) declare @fname varchar(20) declare @lname varchar(30) set @db_name = N'pubs' set @sql = N'use [' + @db_name + N']; set @c = cursor fast_forward read_only for select emp_id, fname, lname from dbo.employee; open @c' exec sp_executesql @sql, N'@c cursor output', @c output if cursor_status('variable', '@c') = 1 begin while 1 = 1 begin fetch next from @c into @emp_id, @fname, @lname if @@error != 0 or @@fetch_status != 0 break select @emp_id, @fname, @lname end close @c deallocate @c end go

Você também pode gostar