none
Llenar cursor desde un Procedimiento Almacenado

    Question

  • Buenos dias,

    el tema es el siguiente: tengo en mi base de datos SQL (2008) varios procedimientos almacenados para definir ciertas reglas que necesito validar, uno de estos procedimientos me duevuelve un conjunto de datos que e puede servir para validar otras reglas, la cuestion es que necesito a NIVEL DE SQL recorrer los registros devueltos por la ejecucion de este procedimiento ya sea llenar un cursor o una tabla temporal. el asunto es tratar los datos del SP a nivel del SQL.

    gracias y agradezco cualquier ayuda.

    Saturday, August 08, 2009 4:46 PM

Answers

  • Hola.

    No discutimos la necesidad de realizar verificaciones en los registros. Lo que discutimos es el mecanismo y un cursor o una tabla temporal no parece lo más óptimo. En todo caso, la tabla temporal te da mucha más versatilidad. Se entiende menos que digas que funciona en unas consultas sí y en otras no. ¿Es que hay más de un procedimiento almacenado? Para que lo puedas cargar en un cursor, el procedimiento debe devolver un conjunto de registros.

    Usando una tabla temporal (has de conocer la estructura del conjunto de registros que te devuelva el procedimiento):

    create table #MiTabla (Campo1 varchar(10), Campo2 int,...)

    insert #MiTabla
    exec MiProcedimiento

    Con los datos de ese procedimiento cargados en una tabla puedes realizar las verificaciones que necesites. Pero sería mejor que pudieras crear otro procedimiento que ya incluyera todas las verificaciones y filtros adicionales y sólo devolviera los registros que necesitas.

    Si nos das detalles (código del procedimiento, verificaciones a realizar y cualquier otro dato que consideres importante) podríamos ayudarte a elaborar este procedimiento que especialice el que ya tienes. Seguro que podrás pasarnos la información suficiente sin comprometer la privacidad de la información que manejas. Con la información que aportas hasta ahora no podemos hacer mucho más que darte alguna idea genérica.



    Alberto López Grande.
    Monday, August 10, 2009 2:13 PM
    Moderator

All replies

  • Hola,

    En T-SQL tienes disponibles ambas alternativas, puedes crear un cursor de servidor y recorrelo (mira CREATE CURSOR, FETCH, ...) en la ayuda tienes ejemplos de cómo hacerlo. También puedes crear tablas temporales, para ello debes nombrarlas como #NombreTabla.

    Ahora, en la mayoría de las ocasiones hay soluciones con mucho mejor rendimiento que el uso de cursores, simplemente hay que cambiar la forma de pensar y orientarlo a conjuntos. Te paso este link que espero que te ayude a cambiar el chip de orientación a filas a orientación a conjuntos:
    http://www.sqlserversi.com/2008/03/piensa-en-conjuntos-de-datos-no-en.html

    Si finalmente deciedes utilizar cursores o tablas temporales y tienes alguna duda concreta nos comentas, y si decides hacerlo orientado a conjuntos también nos comentas. Te recomiendo que nos comentes el problema concreto a resolver intentaremos ayudarte en soluciones concretas.
    -- Un saludo Salvador Ramos Solid Quality Mentors (http://www.solidq.com) --------------------------------------------------- www.helpdna.net (información sobre SQL Server y Microsoft .Net) Visita mi nuevo blog: www.sqlserversi.com ---------------------------------------------------
    Sunday, August 09, 2009 10:04 AM
  • Bueno la respuesta es un poco global, yo se como se crean Cursores y tablas temporales y tambien se que deben ser el ultimo recurso despues de agotar todas las alternativas, pero en este caso era necesario recorrer en el propio motor de SQL los registros devueltos por un SP  y almacenarlos en un cursor o tabla algo asi como este ejemplo que encontre:

    -- Declare a cursor variable to hold the cursor output variable
    -- from sp_cursor_list
    DECLARE @Report CURSOR

    -- Execute sp_cursor_list into the cursor variable.
    EXEC master.dbo.sp_cursor_list @cursor_return = @Report OUTPUT,
          @cursor_scope = 2

    -- Fetch all the rows from the sp_cursor_list output cursor.
    FETCH NEXT from @Report
    WHILE (@@FETCH_STATUS <> -1)
    BEGIN
       FETCH NEXT from @Report
    END


    algo asi es lo que necesito, estube probando de varias maneras y de algunas funcionan de otras no, obviamente cambiando el proc. sp_cursor_list que es del sistema, y si lo recorre pero en cierto tipo de consultas.

    gracias por la ayuda de todas maneras...

    Monday, August 10, 2009 1:45 PM
  • Hola.

    No discutimos la necesidad de realizar verificaciones en los registros. Lo que discutimos es el mecanismo y un cursor o una tabla temporal no parece lo más óptimo. En todo caso, la tabla temporal te da mucha más versatilidad. Se entiende menos que digas que funciona en unas consultas sí y en otras no. ¿Es que hay más de un procedimiento almacenado? Para que lo puedas cargar en un cursor, el procedimiento debe devolver un conjunto de registros.

    Usando una tabla temporal (has de conocer la estructura del conjunto de registros que te devuelva el procedimiento):

    create table #MiTabla (Campo1 varchar(10), Campo2 int,...)

    insert #MiTabla
    exec MiProcedimiento

    Con los datos de ese procedimiento cargados en una tabla puedes realizar las verificaciones que necesites. Pero sería mejor que pudieras crear otro procedimiento que ya incluyera todas las verificaciones y filtros adicionales y sólo devolviera los registros que necesitas.

    Si nos das detalles (código del procedimiento, verificaciones a realizar y cualquier otro dato que consideres importante) podríamos ayudarte a elaborar este procedimiento que especialice el que ya tienes. Seguro que podrás pasarnos la información suficiente sin comprometer la privacidad de la información que manejas. Con la información que aportas hasta ahora no podemos hacer mucho más que darte alguna idea genérica.



    Alberto López Grande.
    Monday, August 10, 2009 2:13 PM
    Moderator
  • Bueno en realidad la tabla temporal parace la solucion mas acertada, es una buena opcion creo que me podra servir. 
    En cuanto lo que dije de que en unas consultas si y en otras no es porque el procedimiento al que quiero recorrerle los registros se llena de forma dinamica a traves de varias consultas, es decir la consulta devuelta es el select de una tabla temporal que se va llenando de unas consultas de otras tablas, pero al devolver el cursor como en el ejemplo de arriba ocurre un error diciendo que el cursor devuelto no tiene un cursor asignado, pero en cambio al hacerlo con una consulta sencilla funciona bien.
    el problema de la tabla temporal es que tengo que tener la estructura de la tabla de forma fija, si el procedimiento es modificado me puede afectar este cambio ya que la tabla no contiene la misma estructura.

    pero creo que me quedare con lo de la tabla temp.

    Monday, August 10, 2009 2:37 PM
  • Hola.

    Mucho me temo que el procedimiento almacenado que recopila los datos no está siguiendo unas buenas prácticas en el desarrollo. No es buena práctica usar código sql dinámico, por cuestiones de rendimiento y de seguridad (posibilita la inyección de sql). No es buena práctica que un procedimiento devuelva una estructura u otra en función de sus parámetros, etc.

    Con ese punto de partida, la elección de cursores o tablas temporales queda en segundo plano, sería mejor que se revisara ese procedimiento almacenado, convirtiéndolo en varios y tratando de que cada parte devuelva siempre la misma estructura, de tal forma que luego pueda tratarse su salida de forma simple. Aunque claro, si tuvieras esa posibilidad puede que no estuvieras haciéndonos preguntas relativas a un procesamiento posterior. En cualquier caso, suerte para salir del paso y si tienes dudas, nos dices.

    Por cierto, en ambos casos, cursor o tabla temporal, deberás conocer la estructura de salida.


    Alberto López Grande.
    Monday, August 10, 2009 2:54 PM
    Moderator
  • Estamos de acuerdo en que el procedimiento no esta hecho de la mejor manera, pero debido a que el desarrollo de basa sobre una BD existente no tengo manera de reestructurar el codigo del SP, creo que la mejor manera sera proponer la creacion de un nuevo SP, o en esta caso de varios.



    Gracias por los consejos...

    Monday, August 10, 2009 3:05 PM