Вы находитесь на странице: 1из 16

Ao del Centenario de Machu Picchu para el mundo

CURSORES EN SQL SERVER

Curso: IMPLEMENTACION DE BASE DE DATOS VII Ciclo

Integrantes: Vsquez Paredes, Pablo Bustamante Auccasi, Janett C rdo!a "ar#n, Carlos Pea $ mez, Ver nica %e&as 'uispe, Jos(

Ica ) Per* 2011

Concepto de Cursores
+na base de datos relaciona como ,'- ,er!er est orientada a con&untos de manera natural, por e&emplo una instrucci n ,.-.C/regresa un con&unto de datos; sin embargo muchas !eces es necesario utilizar no el en#oque de con&unto de datos sino de registros para realizar ciertas operaciones no comple&as, es donde se implementan los cursores. +n cursor es un ob&eto de la Base de 0atos usado por las aplicaciones para manipular los datos #ila a #ila, en lugar de hacerlo en bloques de #ilas como lo hacen los comandos ,'normales. Para poder traba&ar con Cursores, debemos realizar los siguientes pasos: 0eclarar el Cursor con la instrucci n 0.C-A%.. Abrir el Cursor con la la instrucci n 1P.2. %ecuperar las #ilas desde el Cursor con la instrucci n "./C3. Procesar las #ilas obtenidas (modi#icar, eliminar) con la instrucci n +P0A/. / 0.-./. tabla 43.%. C+%%.2/ 1" nombre_cursor. Cerrar el Cursor con la instrucci n C-1,.. .liminar la re#erencia al Cursor 5 liberar memoria con la instrucci n 0.A--1CA/..

Modelo de Cursores
-a sinta6is general para traba&ar con un cursor es la siguiente.

-- Declaracin del cursor FOR

DECLARE <nombre_cursor> CURSOR <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 cursor ...

FETCH <nombre_cursor> INTO <lista_variables> END -- Fin del bucle WH LE -- Cierra el cursor

CLOSE <nombre_cursor>

-- Libera los recursos del cursor

DEALLOCATE <nombre_cursor>
.l siguiente e&emplo muestra el uso de un cursor.

-- Declaracion de variables para el cursor DECLARE @ d int, @!ombre varchar(255),

@Apellido1 varchar(255),

@Apellido2 varchar(255),

@!ifCif varchar(20),

-- Declaracin del cursor

@F"!acimiento datetime

DECLARE cClientes CURSOR FOR SELECT d, !ombre, Apellido1, FROM CL E!TES OPEN cClientes Apellido2, !ifCif, F"!acimiento -- Apertura del cursor -- Lectura de la primera fila del cursor @Apellido2, @!ifCif, @F"!acimiento WHILE (@@FETCH_STATUS = 0 ) BEGIN PRINT @!ombre + ' ' + @Apellido1 + ' ' + @Apellido2 -- Lectura de la siguiente fila del cursor @Apellido2, @!ifCif, @F"!acimiento FETCH cClientes INTO @id, @!ombre, @Apellido1, END

FETCH cClientes INTO @id, @!ombre, @Apellido1,

-- Cierre del cursor CLOSE cClientes -- Liberar los recursos

DEALLOCATE cClientes
Cuando traba&amos con cursores, la #uncion @@"./C3_,/A/+, nos indica el estado de la *ltima instrucci n "./C3 emitida, los !alores posibles son: Valor devuelto 0 -1 -2

Descripci n -a instrucci n "./C3 se e&ecut correctamente. -a instrucci n "./C3 no se e&ecut correctamente o la #ila estaba ms all del con&unto de resultados. "alta la #ila recuperada.

.n la apertura del cursor, podemos especi#icar los siguientes parmetros:

DECLARE <nombre_cursor> CURSOR [ L#CAL | $L#%AL ]

[ F#&WA&D_#!L' | SC&#LL ] [ STAT C | (E'SET | D'!A) C | FAST_F#&WA&D ] [ &EAD_#!L' | SC&#LL_L#C(S | #*T ) ST C ] [ T'*E_WA&! !$ ] FOR >
.l primer con&unto de parmetros que podemos especi#icar es [ -1CA- | $-1BA- ]. A continuaci n mostramos el signi#icado de cada una de estas opciones. LOCAL .speci#ica 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 L#CAL FOR SELECT d, !ombre, Apellido1, FROM CL E!TES
!LOBAL .speci#ica que el mbito del cursor es global para la cone6i n. Puede hacerse por lotes que se e&ecute en la cone6i n. re#erencia al nombre del cursor en cualquier procedimiento almacenado o proceso

Apellido2, !ifCif, F"!acimiento

DECLARE cClientes CURSOR $L#%AL FOR SELECT d, !ombre, Apellido1, FROM CL E!TES Apellido2, !ifCif, F"!acimiento

,i no se especi#ica $-1BA- ni -1CA-, el !alor predeterminado se controla mediante la con#iguraci n de la opci n de base de datos de#ault to local cursor.

.l siguiente con&unto de parmetros que podemos especi#icar es [ "1%4A%0_12-7 | ,C%1-- ]. A continuaci n mostramos el signi#icado de cada una de estas opciones. "OR#ARD_ ONL$

.speci#ica que el cursor s lo se puede desplazar de la primera a la *ltima #ila. "./C3 2.8/es la *nica opci n de recuperaci n admitida.

DECLARE cClientes CURSOR F#&WA&D_#!L' FOR SELECT d, !ombre, Apellido1, FROM CL E!TES
SCROLL .speci#ica que estn disponibles todas las opciones de recuperaci n ("I%,/, -A,/, 0.C-A%. C+%,1% la *nica opci n de recuperaci n que se admite es 2.8/. 2o es posible especi#icar ,C%1-- si se inclu5e tambi(n "A,/_"1%4A%0. P%I1%, 2.8/, %.-A/IV., AB,1-+/.). ,i no se especi#ica ,C%1-- en una instrucci n

Apellido2, !ifCif, F"!acimiento

,i se inclu5e la opci n ,C%1--, la #orma en la realizamos la lectura del cursor !aria, AB,1-+/. ] "%1M <>

debiendo utilizar la siguiente sinta6is: "./C3 [ 2.8/ | P%I1% | "I%,/ | -A,/ | %.-A/IV. |

-- Declaracion de variables para el cursor DECLARE @ d int, @!ombre varchar(255),

@Apellido1 varchar(255), @!ifCif varchar(20),

@Apellido2 varchar(255), @F"!acimiento datetime -- Declaracin del cursor

DECLARE cClientes CURSOR SC&#LL FOR SELECT d, !ombre, Apellido1, FROM CL E!TES OPEN cClientes Apellido2, !ifCif, F"!acimiento

-- Apertura del cursor -- Lectura de la primera fila del cursor FETCH !E+T FROM cClientes

INTO @id, @!ombre, @Apellido1, @Apellido2, @!ifCif, @F"!acimiento WHILE (@@FETCH_STATUS = 0 ) BEGIN PRINT @!ombre + ' ' + @Apellido1 + ' ' + @Apellido2 -- Lectura de la siguiente fila del cursor FETCH !E+T FROM cClientes INTO @id,@!ombre,@Apellido1,@Apellido2,@!ifCif,@F"!acimie nto END -- Lectura de la fila anterior FETCH *& #& FROM cClientes INTO @id, @!ombre, @Apellido1, @Apellido2, @!ifCif, @F"!acimiento PRINT @!ombre + ' ' + @Apellido1 + ' ' + @Apellido2 -- Cierre del cursor CLOSE cClientes

-- Liberar los recursos

DEALLOCATE cClientes
.l siguiente con&unto de parmetros que podemos especi#icar es [ ,/A/IC | 9.7,./ | opciones.

072AMIC | "A,/_"1%4A%0 ]. A continuaci n mostramos el signi#icado de cada una de estas STATIC 0e#ine un cursor que hace una copia temporal de los datos que !a a utilizar. /odas las solicitudes que se realizan al cursor se responden desde esta tabla temporal de tempdb; por tanto, las modi#icaciones realizadas en las tablas base no se re#le&an en los datos de!ueltos por las operaciones de recuperaci n realizadas en el cursor 5 adems este cursor no admite modi#icaciones.

DECLARE cClientes CURSOR STAT C FOR SELECT d, !ombre, Apellido1, FROM CL E!TES Apellido2, !ifCif, F"!acimiento

%E$SET .speci#ica que la pertenencia 5 el orden de las #ilas del cursor se #i&an cuando se abre el cursor. .l con&unto de cla!es que identi#ica las #ilas de #orma *nica est integrado en la tabla denominada :e5set de tempdb.

DECLARE cClientes CURSOR (E'SET FOR SELECT d, !ombre, Apellido1, FROM CL E!TES
D$NAMIC 0e#ine un cursor que, al desplazarse por (l, re#le&a en su con&unto de resultados todos los cambios realizados en los datos de las #ilas. -os !alores de los datos, el orden 5 la pertenencia de las #ilas pueden cambiar en cada operaci n de recuperaci n. -a opci n de recuperaci n AB,1-+/. no se puede utilizar en los cursores dinmicos.

Apellido2, !ifCif, F"!acimiento

DECLARE cClientes CURSOR D'!A) C FOR SELECT d, !ombre, Apellido1, FROM CL E!TES
"AST_ "OR#ARD

Apellido2, !ifCif, F"!acimiento

.speci#ica un cursor "1%4A%0_12-7, %.A0_12-7 con las optimizaciones de tambi(n ,C%1-- o "1%_+P0A/..

rendimiento habilitadas. 2o se puede especi#icar "A,/_"1%4A%0 si se especi#ica

DECLARE cClientes CURSOR FAST_F#&WA&D FOR SELECT d, !ombre, Apellido1, FROM CL E!TES Apellido2, !ifCif, F"!acimiento

.n ,'- ,er!er 2000, las opciones de cursor "A,/_"1%4A%0 5 "1%4A%0_12-7 se e6clu5en mutuamente. ,i se especi#ican ambas, se genera un error. .n ,'- ,er!er 2005, las dos palabras cla!e se pueden utilizar en la misma instrucci n 0.C-A%. C+%,1%. .l siguiente con&unto de parmetros que podemos especi#icar es [ %.A0_12-7 | estas opciones.

,C%1--_-1C9, | 1P/IMI,/IC ]. A continuaci n mostramos el signi#icado de cada una de

READ_ ONL$

.!ita que se e#ect*en actualizaciones a tra!(s de este cursor. 2o es posible hacer o 0.-./.. .sta opci n reemplaza la capacidad de actualizar el cursor.

re#erencia al cursor en una clusula 43.%. C+%%.2/ 1" de una instrucci n +P0A/.

DECLARE cClientes CURSOR &EAD_#!L' FOR SELECT d, !ombre, Apellido1, FROM CL E!TES
SCROLL_ LOC%S

Apellido2, !ifCif, F"!acimiento

.speci#ica que se garantiza que las actualizaciones o eliminaciones posicionadas realizadas a tra!(s del cursor sern correctas. Microso#t ,'- ,er!er bloquea las #ilas cuando se leen en el cursor para garantizar que estarn disponibles para #uturas "A,/_"1%4A%0 o ,/A/IC. modi#icaciones. 2o es posible especi#icar ,C%1--_-1C9, si se especi#ica tambi(n

DECLARE cClientes CURSOR SC&#LL_L#C(S FOR SELECT d, !ombre, Apellido1, FROM CL E!TES
OPTIMISTIC .speci#ica que las actualizaciones o eliminaciones posicionadas realizadas a tra!(s del cursor no se realizarn correctamente si la #ila se ha actualizado despu(s de ser le;da en el cursor. ,'- ,er!er no bloquea las #ilas al leerlas en el cursor. .n su lugar, utiliza comparaciones de !alores de columna timestamp o un !alor de suma de comprobaci n si la tabla no tiene columnas timestamp, para determinar si la #ila se actualizaci n o eliminaci n posicionada genera un error. 2o es posible especi#icar 1P/IMI,/IC si se especi#ica tambi(n "A,/_"1%4A%0.

Apellido2, !ifCif, F"!acimiento

ha modi#icado despu(s de leerla en el cursor. ,i la #ila se ha modi#icado, el intento de

DECLARE cClientes CURSOR #*T ) ST C FOR SELECT d, !ombre, Apellido1, FROM CL E!TES Apellido2, !ifCif, F"!acimiento

Por *ltimo, queda la opci n /7P._4A%2I2$

T$PE_ #ARNIN!

.speci#ica que se en!;a un mensa&e de ad!ertencia al cliente si el cursor se con!ierte impl;citamente del tipo solicitado a otro.

DECLARE cClientes CURSOR T'*E_WA&! !$ FOR SELECT d, !ombre, Apellido1, FROM CL E!TES Apellido2, !ifCif, F"!acimiento

Podemos especi#icar multiples parmetros en la apertura de cursor, pero unicamente un parmetro de cada grupo. Por e&emplo:

DECLARE cClientes CURSOR L#CAL STAT C T'*E_WA&! !$ FOR SELECT d, !ombre, Apellido1, FROM CL E!TES Apellido2, !ifCif, F"!acimiento

Para actualizar los datos de un cursor debemos especi#icar "1% +P0A/. despues de la sentencia ,.-.C/ en la declaraci n del cursor, 5 43.%. C+%%.2/ 1" en la sentencia +P0A/. tal 5 como muestra el siguiente e&emplo.

-- Declaracion de variables para el cursor DECLARE @ d int, @!ombre varchar(255),

@Apellido1 varchar(255), @!ifCif varchar(20),

@Apellido2 varchar(255), @F"!acimiento datetime

-- Declaracin del cursor

DECLARE cClientes CURSOR FOR SELECT d, !ombre, Apellido1, FROM CL E!TES FOR UPDATE Apellido2, !ifCif, F"!acimiento

-- Apertura del cursor OPEN cClientes -- Lectura de la primera fila del cursor FETCH cClientes INTO @id, @!ombre, @Apellido1, @Apellido2, @!ifCif, @F"!acimiento WHILE (@@FETCH_STATUS = 0 ) BEGIN UPDATE Clientes SET A*ELL D#2 = isnull(@Apellido2,'') + ' - )odificado' WHERE CURRENT OF cClientes FETCH cClientes -- Lectura de la siguiente fila del cursor INTO @id, @!ombre, @Apellido1, @Apellido2, END @!ifCif, @F"!acimiento

-- Cierre del cursor CLOSE cClientes -- Liberar los recursos

DEALLOCATE cClientes

Tipos de Cursores
10BC 5 A01 de#inen cuatro tipos de cursores admitidos por Microso#t,'- ,er!er. -a instrucci n 0.C-A%. C+%,1% se ha ampliado para que pueda especi#icar cuatro tipos para en el con&unto de resultados 5 en los recursos que consumen, como la memoria 5 el espacio los cursores de /ransact-,'-. .stos cursores !ar;an en su capacidad para detectar cambios de te&pd'. +n cursor puede detectar cambios en las #ilas s lo cuando intenta recuperarlas una segunda !ez. .l origen de datos no puede noti#icar al cursor las modi#icaciones in#lu5e tambi(n en la capacidad de un cursor para detectar los cambios. Cursores est(ticos ( STATIC) realizadas en las #ilas recuperadas actualmente. .l ni!el de aislamiento de la transacci n -os cuatro tipos de cursor de ser!idor de la API que admite el ser!idor ,'- ,er!er son: 0e#ine un cursor que hace una copia temporal de los datos que !a a utilizar. /odas las solicitudes que se realizan al cursor se responden desde esta tabla temporal de tempdb; por tanto, las modi#icaciones realizadas en las tablas base no se re#le&an en los datos de!ueltos por las operaciones de recuperaci n realizadas en el cursor 5 cambio, 5 consumen relati!amente pocos recursos al desplazarse. adems este cursor no admite modi#icaciones. 0etectan pocos cambios o ning*n

Cursores din(&icos ( DINAMIC)

0e#ine un cursor que, al desplazarse por (l, re#le&a en su con&unto de resultados todos los cambios realizados en los datos de las #ilas. -os !alores de los datos, el orden 5 la pertenencia de las #ilas pueden cambiar en cada operaci n de recuperaci n. -a opci n de recuperaci n AB,1-+/. no se puede utilizar en los cursores dinmicos. 0etectan todos los cambios pero consumen ms recursos al desplazarse.

Cursores de s lo avance ( "AST_ "OR#ARD)

.speci#ica un cursor "1%4A%0_12-7, %.A0_12-7 con las optimizaciones de tambi(n ,C%1-- o "1%_+P0A/..

rendimiento habilitadas. 2o se puede especi#icar "A,/_"1%4A%0 si se especi#ica

Cursores controlados por con)unto de claves ( %E$SET)

.speci#ica que la pertenencia 5 el orden de las #ilas del cursor se #i&an cuando se abre el cursor. .l con&unto de cla!es que identi#ica las #ilas de #orma *nica est integrado en la un consumo menor que los cursores dinmicos. tabla denominada :e5set de tempdb. ,e encuentran entre los dos anteriores, pero con

Aunque los modelos de cursor de la API de base de datos consideran el cursor de s lo a!ance como un tipo ms, ,'- ,er!er no establece esta distinci n. ,'- ,er!er considera que las opciones de desplazamiento de s lo a!ance 5 de desplazamiento son las que se pueden aplicar a los cursores estticos, a los controlados por con&unto de cla!es 5 a los dinmicos.

Creaci n de Cursores
-a sinta6is de declaraci n de un cursor es la siguiente: declare cursor_prueba cursor #or selec nombres, apellidos #rom persona /*ahora declaramos las !ariables con las que !amos a recorrer el cursor:*/ declare @nombres !archar(25)

declare @apellidos !archar(25) /*Abrimos el cursor para iniciar el recorrido del mismo*/ open cursor_prueba

/*,e mue!e al siguiente registro dentro del cursor 5 los asignamos a las !ariables antes declaradas*/

#etch ne6t #rom cursor_prueba into @nombres, apellidos

/*%etorna el estatus del *ltimo registro recorrido en el cursor, cuando es igual a 0 encontr registro pendientes de recorrer*/ <hile @@#etch_status = 0 begin

print '.l 2ombre de la persona es: ' + @nombres + ' 5 sus apellidos: ' + apellidos /*,e mue!e al siguiente registro dentro del cursor*/ #etch ne6t #rom cursor_prueba into @nombres, apellidos end /* Cuando concluimos con el recorrido del cursor, este debe ser cerrado 5 luego destru;do

mediante las siguientes sentencias:*/

close cursor_prueba --Cierra el cursor.

0eallocate cursor_prueba ---o libera de la memoria 5 lo destru5e. -os cursores son mu5 e#icientes para utilizarlos en Job de las base de datos que realizen alguna operaci n donde necesitemos modi#icar alguna in#ormaci n dentro de un bucle. -os cursores demandan mucho del ser!idor de base datos, por lo tanto, no es recomendable abusar del mismo, 5a que necesitan bastante recursos para su e&ecuci n

Utili*aci n de Cursores
.n una Base de 0atos llamada Al&acen_ carnet, aadiremos una tabla 2ombrecito mediante el siguiente script:

Como puede !er se insertaron registros 5 el campo de nombre completo no se ingreso correctamente, por lo que tendremos que actualizar registro por registro, para ello haremos uso de cursores.

Вам также может понравиться