Maestros del Web


Estás en Inicio / Editorial / Bases de Datos

16.02.2005

Cursores en SQL Server

Los cursores son una herramienta de SQL que nos permite recorrer el resultado de una consulta SQL y realizar operaciones en cada paso de ésta.

Cursores SQlEs así como nos ayuda a realizar operaciones que de otro modo serían más complejas o irrealizables. A continuación coloco el código de un cursor muy simple para el Analizador de Consultas de SQL Server.

   /* Este cursor deja las contraseñas 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 sólo 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

Califica esta nota:

1 estrella2 estrellas3 estrellas4 estrellas5 estrellas (19 votos, promedio: 3.84 de 5)
Loading ... Loading ...

Sobre el autor

Matías Thayer M.
Encargado del sitio de Webmagic, uno más de los miles de sitios para webmasters ;)

Si eres nuevo en Maestros del Web y te agradan nuestras publicaciones, te invitamos a suscribirte a nuestro Feed.

Sindícanos en: Google Reader, Bloglines, My Yahoo o My MSN | ¿Qué es el Feed?

Comentarios

63 comentarios en total.

  1. Mickel 26.02.2005 - 19:46 - #

    Solo que, segun entiendo, la recomendacion de MS para SQL Server es usar tablas temporales u otras tecnicas en lugar de cursores. Algun comentario?

  2. TomaHawkk 28.02.2005 - 10:25 - #

    Los cursores en Sql server son lentos y si son recursivos sin comentarios…

  3. Jorge_Mota 01.03.2005 - 10:34 - #

    si, en cuanto a rendimiento siempre sera mejor usar tablas temporales, aun que hay ocasiones que son imprescindibles, lo mejor es tratar de minimizar la cantidad de acciones que tomemos con el cursor, y lo que es mas, el select que utilizemos para el cursor, debera traer los registros exactos que necesitemos, y no luego filtrar el resultado obtenido en el cursor :)

    hay muy buenos comentarios,por gurus de sql (en español) en este site

    http://www.portalsql.com

    Saludos

  4. morrey33 29.03.2005 - 16:47 - #

    Cuando es conveniente usar cursores y cuando tablas temporales ?
    Quiza las aplicaciones que he hecho no son tan complicadas como para pensar en eso, pero me gustaria saber.
    Muchas gracias

  5. Mickel 29.03.2005 - 19:35 - #

    Creo que nunca es conveniente usar cursores a no ser que necesariamente tengas que recorrer los registros uno a uno y hacer operaciones.

  6. rlivon 02.04.2005 - 03:46 - #

    En General siempre se puede actualizar las tablas temporales con actualizaciones masivas de datos. Con o sin tablas #temp_
    Los cursores son un retorno al dbf, donde todo se hacía recorriendo registro a registro, pero en esa época no había otra opción.
    Particularmente creo que el uso de cursores simplifica la solución de un problema, pero complica el código haciéndolo legible solo para el que lo hizo.
    Si se decide quemar alguna neurona más, se podrá encontrar una opción que solucione el problema sin el uso de cursores. De eso estoy seguro, pero siempre habrá por allí gente que piense que cuanto más complicado programe, más tiempo durará en su trabajo. Claro que ninguno de nosotros nos identificamos con esta gente. ¿No?

  7. leonixya 09.06.2005 - 09:48 - #

    Una pregunta para uds que parece que entienden bastante este tema de los cursores.
    En mi laburo tenemos un sistema a medida hecho en clarion el cual ultimamente se cierra en los clientes con un error gpf, varias veces por dia.
    viendo un trace del profiler descubri que aparecian frecuentemente exceptions en classevent tales como: Error: 1933, Severity: 16, State: 1
    Error: 16954, Severity: 10, State: 1
    Error: 213, Severity: 16, State: 7
    Error: 1934, Severity: 16, State: 1
    Error: 245, Severity: 16, State: 1
    y estos aparecen casi siempre luego de un rpc:completed relacionado con cursores
    exec sp_cursorclose 180152853 o
    exec sp_cursorfetch 180152853, 2, 1, 20 o
    exec sp_cursorunprepare 7167
    Estos cierres del sistema se pueden deber a este uso de cursores ??
    Es dificil para mi verificar si es un problema de programacion(no tengo el fuente) o un problema de las memos(hard) de los clientes ?
    Hay en algun lugar informacion de los problemas que pueden surgir de la utilizacion de los cursores?
    gracias

  8. No Registrado 06.07.2005 - 15:48 - #

    Hay que saber cuando usar y no usar cursores. Estos son muy utiles para cierto tipo de operaciones sobre todo en un sistema transaccional, y el uso indiscriminado de tablas temporales puede dar un rendimiento muy pobre a la aplicación (http://www.programacion.net/bbdd/articulo/man_tablastemp/). Me ha tocado ver aplicaciones donde el uso de tablas temporales a provocado que las aplicaciones respondan muy pobremente. También hay que ver que cosas procesar en el servidor y que en el cliente, un error muy comun que hacen las personas que programan en visual basic y que están acostumbradas a hacer todo el procesamiento en el lado del cliente, inclusive no aprovechando la integridad referencial que el mismo manejador de base de datos maneja.

    salu2.

  9. Jorge Mota 31.10.2005 - 13:20 - #

    para los que vuelven a leer esto, o ingresen nuevamente, ahora que he visto este articulo de nuevo caigo en un error en el codigo que no identifique antes…

    declare @cod as int
    declare @user as varchar(50)
    declare @pass as varchar(50)
    esto deberia estar asi:

    declare @cod as int, @user as varchar(50), @pass as varchar(50)

    es decir en un solo declare, ya que es mas optimo para el sql server (segun la ayuda misma).

    asi que pueden aprovechar este pequeño tip para optimizar sus querys y sp donde hagan uso del declare en varias lineas.

    tambien prefieran las funciones definidas por el usuario ante los procedures :D
    son mas optimas :D

  10. JULS 22.05.2006 - 17:21 - #

    Ese ejemplo es una verguenza que clases de Ing. Informatico sos ???

  11. Francisco FBL 07.06.2006 - 09:37 - #

    Los cursores son buenos cuando estamos hablando de menos de 300 registros, las tablas temporales seria la mejor opción, pero si sabemos que la tabal temporal podria tener unos 1000 registros mejor utilecemos una variable de tipo table en lugar de la tabla temporal que se crea en el disco en la bd de Tempdb

  12. Carlos 04.07.2006 - 14:21 - #

    Todo esto es una mierda,aprenda a programar bien para que no usen esa basura de cursores

  13. francisco alberto 06.07.2006 - 18:21 - #

    tigueres eso no deja efectivo aprendan a manejar softwares que dejen dinero

  14. julio 12.07.2006 - 07:54 - #

    quiero saber sobre analizador de consultas y como puedo crear una base de datos en ella. julio_ut@hotmail.com

  15. stvmty 12.07.2006 - 16:05 - #

    En ocasiones hay que medir cual es la mejor opción de hacer las cosas. Justo ahora tengo dos opciones para cumplir un requerimiento de un sistema que estoy haciendo: Hacer los cálculos desde la BD usando cursores (ugh!) o hacer los cálculos desde la aplicación con muchisimos querys volando por aqui y por allá a través de la internet!!!

    Pues si, los cursores deben ser la _última_ opción para cualquiera.

    // http://stvmty.no-ip.info/ //

  16. Xtreme 25.07.2006 - 00:18 - #

    ¿Qué eso es lo poco que pueden publicar y encima piden que lo valore?
    -Falta mas acerca de cursores

  17. Gustavo 04.08.2006 - 09:23 - #

    En el mundo de las bases de datos es muy común la utilización de tablas temporales. A pesar de que todo el mundo sabe que este tipo de estructuras ralentizan el funcionamiento de nuestras consultas, los programadores no pueden evitar recurrir a ellas porque muchas veces facilitan la resolución de problemas. Almacenar datos para usarlos posteriormente, guardar resultados parciales, analizar grandes cantidades de filas. Hay muchos casos en los que podemos necesitar estas tablas temporales, ¡Pero hay que utilizarlas correctamente!
    Tomado de: http://www.programacion.com/bbdd/articulo/man_tablastemp/

  18. Sónico 17.08.2006 - 18:12 - #

    Prefiero las cosas sencillas y sin complicaciones…pero pues cada quien programa como quiere !!!

    Saludos a todos

  19. PAZ 24.08.2006 - 09:40 - #

    HOLA A TODOS, quiero saber como hago para borrar campos,todos los fin de mes, y se abran a las 01:00 AM del primer dia del mes siguiente.
    Gracias

  20. PAZ 24.08.2006 - 09:40 - #

    HOLA A TODOS, quiero saber como hago para borrar campos,todos los fin de mes, y se abran a las 01:00 AM del primer dia del mes siguiente.
    Gracias

  21. Greivin 30.08.2006 - 12:18 - #

    Una consulta:

    Tengo que realizar la inserción de todo un select en otra tabla(historica) agregando algun dato adicional, la preguna es:

    -¿Es mas eficiente realizar una o dos consultas para obtener los datos y que mi aplicación realice los calculos, para despues insertarlos en la base de datos?
    - ¿Es eficiente hacerlo con cursores?
    - Cual de las dos opciones brinda mayor velocidad? En una red de área local.

  22. No Registrado 13.09.2006 - 03:31 - #

    JULS;1557896, Ese ejemplo es una verguenza que clases de Ing. Informatico sos ???

    Y vos que clase de Ing. sos?, mejor ofrece una buena solucion para lo que aqui se pregunta y se discute…

  23. FERNANDO 13.09.2006 - 12:30 - #

    Necesito poder detener el bucle del cursor… aqui hemos desarrallo una migracion de datos diaria en lotes… lo que ocurre es que lo realiza bien, pero cuando llega al ultimo dato sigue regresando con el mismo valor indefinidamente… se ve que el

    while @@fetch_status = 0

    NO LO PUEDE DETENER!!!

  24. pichonservis 18.09.2006 - 18:42 - #

    salu2
    bueno me parecio bueno el tuto aprendi un poco..y bueno algunas cosas que nada mas no entendia alli aprendi…gracias y suerte a todos….

  25. Mickel 18.09.2006 - 18:49 - #

    Greivin;1680275, Una consulta:

    Tengo que realizar la inserción de todo un select en otra tabla(historica) agregando algun dato adicional, la preguna es:

    -¿Es mas eficiente realizar una o dos consultas para obtener los datos y que mi aplicación realice los calculos, para despues insertarlos en la base de datos?
    - ¿Es eficiente hacerlo con cursores?
    - Cual de las dos opciones brinda mayor velocidad? En una red de área local.

    Es mas eficiente que hagas un
    INSERT INTO
    SELECT

  26. Ing.1984 19.09.2006 - 13:38 - #

    este tema es buenisimo

  27. Leo... 21.09.2006 - 13:01 - #

    …me gustaria me dijeran cual es el objetivo o ventaja principal de usar cursores , de esta forma me quedaria claro cuando debo y cuando no debo usarlos.

  28. kofmaster 26.09.2006 - 15:56 - #

    nesecitamos hacer una uelga global para que el mundo comprenda que tan importante somos nosotros y aprendan a valorar los sistemas y nos paguen como es debido.

    // http://seminarioutp.serverhttp.org/ // //

  29. May 17.10.2006 - 09:41 - #

    hasta cuando cursores por dios , ahora seguro quieren programar en basic, cambien el paradigma

  30. Axel 18.10.2006 - 20:43 - #

    Quiero te ner un cursor pero el mismo cursor no quiero otro diferente

  31. lizbeth rivera 06.11.2006 - 22:49 - #

    no encontre lo que andaba buscando

  32. Sergio Gómez 09.11.2006 - 14:44 - #

    Los Cursores son una mierda complican el laburo.
    tengo una aplicación en VB 6 pero
    todo está hecho con Store Procedure con Cursores.
    Parecen que la gente que laburo antes no sabían trabajar en equipo.

  33. marlo 04.12.2006 - 12:46 - #

    es super básica la explicación pero sirve de todas formas.

  34. Luis 05.12.2006 - 18:37 - #

    Buenoooo, la verdad es que con cursores se abre un abanico de posibilidades, de que hacer con cada linea de una tabla, que con otras sentencias sql no se puede hacer por ello de su existencia hasta ahora, asi que doy un voto por a los cursores, y para los que preguntan de como hacer que a cierta hora y fecha se haga algo el equipo relacionado con la base de datos, pues genera la aplicacion que elimine los datos o agregue datos aqui uno hace lo que desee con su aplicacion generas tu ejecutable, luego en el programador de tarea asigna una tarea de que cada fin de mes a la hora que necesite se ejecute esa aplicacion como ejemplo (miaplicacion.exe) y listo, y tambien recordaros que con procedimientos almacenados que ya estan compilados en el mismo servidor de base de datos las sentencias son mas rapidas que escribir las sentencias en el programa, y para el amigo que necesita saber si con una o dos consultas pues con una sola anidada asigna el insert de una seleccion que ya trae el calculo en la misma sentencia.
    Atte. Luis

  35. MaD 12.12.2006 - 11:21 - #

    Muchos comentarios hasta con tintes racistas hacia los cursores no?…
    Es Simple.. No uses Cursores ni Tablas temporales…
    Claro q hay muchos casos q no puedes hacer otra cosa mas q emplear alguno de estos recursos, pero el error radica en inmediatamente pensar en un cursor, el 80% de las cosas que se hacen con cursores se pueden hacer usando bien subquerys…
    o estoy mal?..
    Saludos…

  36. Rama 22.12.2006 - 03:54 - #

    Existe alguna forma de definir la cadencia de un cursor, es decir, cada cuanto tiempo va de un paso a otro?
    Como meterle una pausa o algo asi…

  37. Alecks 28.12.2006 - 13:05 - #

    Una forma de evitar los cursores es la utililización de Sub Consultas asi no se tiene que procesar mediante un cursor. o utilizar variables de tipo table para que sea mas rapido el proceso de recorrer el cursor para evitar que la tabla(s) se bloqueen

  38. JAMES 23.01.2007 - 16:22 - #

    HOLA AMIGOS ESTOY HACIENDO UN PEQUEÑO SISTEMA DE PRESTAMO DE EQUIPOS AUDIOVISUALES NECESITO SU AYUDA. EL PROBLEMA ES EL SIGUIENTE TENGO UNA TABLA PRESTAMOS DONDE TENGO LOS CAMPOS NOMBREEQUIPO, FECHAUSO,HORAUSO,FECHAFINAL,HORAFINAL. EL CHISTE ES NO SE PERMITA QUE SI UN EQUIPO YA ESTA RESERVADO A LA HORA INDICA Y FECHA NO PERMITA QUE SE PUEDA RESERVAR Y QUE VERIFIQUE LAS HORAS Y FECHAS DISPONIBLES.. NO SE SI ME EXPLIQUE

  39. CARLOS 15.02.2007 - 23:15 - #

    PUEDES TRABAJARLO CON UN ESTADO DENTRO DE LA MISMA TABLA, EL CUAL T INDICARA SI EL EQUIPO ESTA RESERVADO O YA ESTA EN PRESTAMO

  40. Alejandro 19.02.2007 - 12:56 - #

    Yo de nuevo cai en este articulo pedorr, qiuero saber cual es la limitacion de los cursores y uds pelotudean

  41. anonimo 08.03.2007 - 09:02 - #

    que webean argentinos culiaos

  42. Eugenia 13.03.2007 - 08:41 - #

    con respecto a la pregunta de Paz debes crear una tarea en SQL que sea una vez al mes e indicandole la hora de ejecución de tu procedimiento.

  43. RAFAEL 13.03.2007 - 15:16 - #

    COMO PUEDO CAMBIAR UN REGISTRO SI EL CAMPO ES ES PRIMARIO EJM: SI EL RANGO ESTA DE (761-1114) AL (1-105)
    LO HE INTENTADO CON EL UPDATE

  44. Helen 27.08.2007 - 16:20 - #

    Pues a mi si me sirvió el artículo publicado creo que al menos deja claro cual es el papel del cursor y me resolvió mis dudas creo que si tan buenos son deberían de poner el equivalente del ejemplo del artículo pero sin usar cursores no creen, esto es para los expertos en sql saludos

  45. Luis Arcuri 21.09.2007 - 09:23 - #

    Yo no soy ningún experto, pero el cursor de arriba podría reeplazarse por:

    UPDATE CLIENTES SET CLIPASS = CLIUSER FROM CLIENTES

    si se quisiera poner alguna condicion podría ponerse una clausula where …

  46. Jorge Muchica 23.09.2007 - 17:14 - #

    entiendo q el cursor segun lo q se comenta en el articulo, se parece como una lista enlasada, donde solo tienes acceso a un registro a la vez, su facilidad de consultarlo. Ummm pq le pusiseron nombre CURSOR???

  47. Jorge 26.11.2007 - 11:49 - #

    Toda esta discusión es una tontería. Es como discutir si solo alcanza con el cuchillo para comer y dejamos de usar el tenedor…
    La experiencia les dirá cuando conviene usar una herramienta u otra. Yo les digo que si las tablas tienen millones de registros, el hacer un UPDATE es suicida porque tarda horas y mientras tanto, la tabla bloqueada… Ahí los cursores permiten partir la operación en muchos pequeños bloques que permiten al resto de los usuarios seguir trabajando.

  48. enrique 12.12.2007 - 14:59 - #

    como puedo llamar de sql a visual basic.net?????

  49. Bayta Darell 24.01.2008 - 11:15 - #

    Se puso buena la discusión de los cursores. mas q el contenido del articulo en sí.

    Sí, sí… Los cursores no son muy eficaces q digamos, al igual que las subconsultas, y si hablamos de cursores mezclados con subconsultas la cosa esta bien jodida.

    Saludos!

  50. sandra 13.02.2008 - 05:43 - #

    me podrian ayudar con algo, es que tengo que hacer un procedimiento que sea recursivo pero cuando le meto los cursores, cada vez que hace la recursividad me sale error de que el cursor ya esta abierto, la idea es que el procedimiento me lea un arbol de arriba a abajo y que me de los descendientes de un nodo.

  51. Luis Arcuri 14.02.2008 - 08:05 - #

    Sandra, haceme acordar que no te deje tocar mi servidor de base de datos… Es que usar cursores recursivos… espero que no sea grande la Base.
    En cuanto al Update, es mucho más rápido que usar cursores, y si haces update a toda la tabla deberá demorarse lo necesario, aunque no necesariamente tenes que hacerlo sobre toda la tabla, pero es la opción más rápida. Además deberán cuidar los índices de las tablas que se esten leyendo para hacer el update.

  52. mgavilat 15.02.2008 - 10:09 - #

    Un mensaje para el usuario JULS
    Es un grosero y descortes. Deja que cada quien exprese lo que conoce. Tu decides si lo usas o no.

  53. gusta1308 08.04.2008 - 22:20 - #

    Voto por no usar nada que no sean consultas o subconsultas, sin embargo he tenido que generar reporte generenciales complejos y utilizo los recursos en el siguiente oden prioridad: variables de tablas, cursores y por ultimo tablas temporales fijas, nada ##temp, trabajo para una trasnacional donde el uso de dbTemp por parte de una ##temp hay que pagarlo a parte. Y los cursores son realmente rapidos, la lentitud en ellos radica generalmente en las operaciones que se hacen por cada linea de ejecución, sin embargo para SQL Server 2000 existe un bug que ocurre cuendo corremos un cursor sobre una variable de tabla, donde el servidor se queda sin hacer nada y consumiendo memoria al rededor de 15 mins.

  54. gusta1308 08.04.2008 - 22:24 - #

    Y por ultimo alguien pidio la mas simple que los cursores existe, se conoce como cursores no estandar o clausula FOR, esta presente en servidores como Interbase/Firebird, Postgre entre otros

  55. oxiens 16.05.2008 - 18:44 - #

    SI ALGUIEN ME PODRIA AYUDAR EN ESTE PROBLEMA:
    TENGO UN CURSOR, PERO EN CIERTA CONDICION NECESITO SALIRME DEL CURSOR PORQUE YA NO NECESITO QUE RECORRA TODO EL CURSOR.
    cOMO PUEDO HACER?

  56. arf 10.06.2008 - 04:40 - #

    CALLESE PUTO HOYGAN!

  57. Xio 06.08.2008 - 16:05 - #

    Graicias

  58. salas 14.08.2008 - 11:52 - #

    soy un novato en la BD’s pero a pero a pesar de todo pude aprender un poco de ustedes gracias. (Salas “UAIM”)

  59. Richard 14.08.2008 - 15:32 - #

    Respecto al uso de cursores me parece bien tener cada fila en detalle, porque puedo manipularlo de una mejor forma, pero cuando en la BD existe muchos registros, manejarlo a detalle ya se complica… como dijeron muchos hay que ver cuando usar cursores y cuando no…

  60. Fantasmita 28.08.2008 - 16:19 - #

    PAZ

    Tienes que crear una Tarea en la parte de MANAGEMENT de SQL Server y activar el SQL Server Agent para que este pueda ejecutar las tareas a la hora que necesitas que pase.

    ————–
    “Quiero saber como hago para borrar campos,todos los fin de mes, y se abran a las 01:00 AM del primer dia del mes siguiente.”

  61. Fantasmita 28.08.2008 - 16:28 - #

    Por lo que veo aquí hay mucha gente que le vale un pepino como hacer las cosas, por ese tipo de gente he tenido muchos problemas cuando hago reingenieria de procesos para bases de datos y código duro.

    Ojalá aprendieran a optimizar sus desarrollos y dejar que ciertas acciones las realice el servidor y ciertas acciones el cliente.

    Si no saben lo que es programar en CAPAS entonces realmente están haciendo trabajo que sus empresas NO deberian pagar y generando problemas a desarrolladores y consultores que realmente optamos por aprovechar todos los recursos de ambas partes (Cliente-Servidor).

    Saludos.

  62. Fantasmitta 28.08.2008 - 16:28 - #

    Por lo que veo aquí hay mucha gente que le vale un pepino como hacer las cosas, por ese tipo de gente he tenido muchos problemas cuando hago reingenieria de procesos para bases de datos y código duro.

    Ojalá aprendieran a optimizar sus desarrollos y dejar que ciertas acciones las realice el servidor y ciertas acciones el cliente.

    Si no saben lo que es programar en CAPAS entonces realmente están haciendo trabajo que sus empresas NO deberian pagar y generando problemas a desarrolladores y consultores que realmente optamos por aprovechar todos los recursos de ambas partes (Cliente-Servidor).

    Saludos.

  63. Fantasmitta 28.08.2008 - 16:47 - #

    JAMES

    El problema NO consiste en SQL Server, la cosa está en la capa de Negocio que es cuando extrae la información de la capa de Base de datos (Conexion) y tú decides si sólo lo muestras como Lectura o envias un mensaje en el que le digas al usuario que ya está reservado.

    ————–
    HOLA AMIGOS ESTOY HACIENDO UN PEQUEÑO SISTEMA DE PRESTAMO DE EQUIPOS AUDIOVISUALES NECESITO SU AYUDA. EL PROBLEMA ES EL SIGUIENTE TENGO UNA TABLA PRESTAMOS DONDE TENGO LOS CAMPOS NOMBREEQUIPO, FECHAUSO, HORAUSO, FECHAFINAL, HORAFINAL. EL CHISTE ES NO SE PERMITA QUE SI UN EQUIPO YA ESTA RESERVADO A LA HORA INDICA Y FECHA NO PERMITA QUE SE PUEDA RESERVAR Y QUE VERIFIQUE LAS HORAS Y FECHAS DISPONIBLES.. NO SE SI ME EXPLIQUE.

Deja tu Comentario


Maestros del Web se reserva el derecho de moderación de los comentarios. Evita utilizar palabras soeces, ataques directos, descalificativos, insultos, de lo contrario tu comentario será eliminado.


-


Maestros del Web es el punto de encuentro para los entusiastas de la red.

Creative Commons by-nc-sa 3.0 | Política de Privacidad | CMS: Wordpress