locked
Resultado de un Procedure a un valor escalar RRS feed

  • Pregunta

  • Hola, tengo un storedProcedure que me regresa en una tabla

    un valor, ésta tabla solo cuenta con un campo y un registro

    como puedo asignar el resultado de ese stored a una variable?

    se puede? existe algún truco?

    muchas gracias


    saludos

    lunes, 13 de agosto de 2012 19:08

Respuestas

  • Pues qwalgrande tiene un buen punto y sería genial una compilación de lo que está tratando de hacer.  Pero bueno, creo que finalmente ya entendí con eso que mencionó de CURSOR.  El procedimiento almacenado ese que devuelve una fila con precio mínimo tiene que correrse una vez por registro.

    Entonces sí:  Si no quiere tocar el procedimiento almacenado no le queda más que un cursor:

    Declare c Cursor For Select.... -- Aquí va el select primero que genera las filas a usar.
    
    --Declare una variable por cada campo de columna.
    --No sé bien los tipos de datos porque usted no muestra
    --la estructura de la tabla.  Corrija los tipos según
    --convenga.
    Declare @fecha int;
    Declare @TV nchar(1);
    Declare @serie int;
    Declare @tasa float;
    Declare @tarifa float;
    Declare @inst2 nvarchar(50);
    
    --Declare una variable de tabla para recoger los resultados:
    Declare @r Table
    (
        Fecha int
        , TV nchar(1)
        , Serie int
        , Tasa float
        , Tarifa float
        , inst2 nvarchar(50)
        , PrecioMin money
    );
    
    --Cree la tabla temporal según el formato de los datos devueltos por el
    --procedimiento almacenado.  Agregue una clave primaria.
    Create Table #tmp
    (
        ID int Not Null Identity(1, 1) Primary Key
        , PrecioMin money
        , ...
    );
    
    --Variable para extraer el resultado del procedimiento almacenado.
    Declare @pMin money;
    
    Open c;
    Fetch Next From c Into @fecha, @TV, @serie, @tasa, @tarifa, @inst2;
    While @@Fetch_Status = 0
    Begin
        Insert Into #tmp
    	exec dbo.tCIA_GeneraParametros @fecha, @TV, @serie, @tasa, @tarifa  -- CREO que esos son los valores correctos.
    	
    	Select Top 1 @pMin = PrecioMin From #tmp Order By ID Desc;
    	--Inserte ahora el resultado en la variable resultado:
    	Insert Into @r
    	Values (@fecha, @TV, @serie, @tasa, @tarifa, @inst2, @pMin);
        Fetch Next From c Into @fecha, @TV, @serie, @tasa, @tarifa, @inst2;
    End
    
    --Listo.  Muestre el resultado:
    Select * From @r;
    

    Si hubiera tenido la estructura de las tablas, el resultado hubiera podido ser obtenido mediante un INNER JOIN en vez de tener que usar una variable tipo Tabla (@r).


    Jose R. MCP
    Code Samples

    • Marcado como respuesta kakaroto2012 martes, 14 de agosto de 2012 17:40
    martes, 14 de agosto de 2012 16:56

Todas las respuestas

  • Mejor convierte el SP a una función escalar:

    Create Function dbo.fnNombreFuncion
    Returns TipoDeResultado
    As
    Begin
        Declare @resultado TipoDeResultado;
        -- Calcule el resultado aquí.  Puede usar un SELECT.
        -- Ejemplo:
        Select Top 1 @resultado = NombreDeColumna
        From NombreDeTabla
        Order By NombreDeColumna;
    
        return @resultado;
    End
    Go
    



    Jose R. MCP
    Code Samples

    lunes, 13 de agosto de 2012 19:14
  • Fijate el ejemplo C de este link con la palabra output en los procedimientos almacenados:

    http://msdn.microsoft.com/es-bo/library/ms187926(v=sql.105).aspx


    MVP MCT MCTS Daniel Calbimonte

    http://elpaladintecnologico.blogspot.com

    lunes, 13 de agosto de 2012 19:21
  • declare @tabla table ( campo  varchar(30) )
    declare @variable as varchar(30)
    
    insert into  @tabla
    exec tuSP ;
    
    
    select @variable=campo from @tabla;
    
    print( @variable );

    SALUDOS
    lunes, 13 de agosto de 2012 19:23
  • Hola, muchas gracias por sus respuestas, funcionan pero mi problema es más grande

    quiero ejecutar una consulta, + el valor que me regresa éste stored procedure

    el stored procedure es tan grande y complejo, que no puedo meterlo en una función

    ahora, ya pude asignar el resultado a una variable, pero allí todavía no me sirve, porque 

    quise meter ese valor de la variable a una función, para ahora si, ejecutar mi consulta

    con el resultado escalar de esa función

    Pero las mugres funciones no aceptan INSERTS, tampoco tablas temporales 

    intenté con el truco del OutPut que regresa un stored, pero tampoco, se lo asigna bien a una variable

    y compila, pero al momento de la ejecución me regresa un error jeje

    en realidad lo que necesito es que el resultado de ese stored procedure actúe como una función 

    pero no he podido, las funciones me restringen demasiado,

    creo que no se puede  =(


    saludos

    lunes, 13 de agosto de 2012 19:47
  • No entiendo el problema: Chankrovsky te mostro como extraer la salida del procedimiento almacenado a una tabla,
    y WebJose te mostro como extraer valores de la tabla (y utilizarlos como parametros de una función).

    El castellano no es mi lengua materna. Discúlpenme por los errores gramaticales, y, si pueden, corríjanme en los comentarios, o por correo electrónico. ¡Muchas gracias! Blog: http://about.me/GeriReshef

    lunes, 13 de agosto de 2012 20:08
  • Así es, pero aun así, no puedo resolver mi problema, 

    es que tengo una tabla, con un campo llamado monto, el cual, lo quiero multiplicar por el resultado que

    me entrega un stored procedure, 

    Pero desde una consulta no puedo llamar a un stored procedure, por lo tanto, quise meter ese stored

    dentro de una función para poderla llamar desde una consulta cualqueira

    EL PROBLEMA es dentro de la función, en tiempo de ejecución, no me permite regresar el resultado del stored como valor escalar.

    aun con los trucos mostrados anteriormente, ya le intenté mil, y pues no se puede  =(

    una función no acepta llamar stored con OUTPUT, no acepta INSERTS, no acepta tablas temporales

    y así....


    saludos

    lunes, 13 de agosto de 2012 20:34
  • Pero desde una consulta no puedo llamar a un stored procedure

    ¿A qué llama usted una "consulta"?  Porque en T-SQL puede llamar a un SP sin problema.


    Jose R. MCP
    Code Samples

    lunes, 13 de agosto de 2012 20:53
  • Obviamente no estamos comprendiendo tu problema, porque no nos copias tu codigo y nos explicas que es lo que no te sale, y vemos que se puede hacer :)

    SALU2 !

    martes, 14 de agosto de 2012 13:12
  • ok ok

    Tengo una consulta así....

    FECHA     TV    SERIE      TASA      TARIFA       INSTRUMENTO2

    --------- ----- ---------- --------- ------------ ------------

    41135     M     241205     5.41      5.41375      FIJA

    41135     M     241205     5.42      5.422        FIJA

    41135     M     220609     5.34      5.3422       FIJA

    41135     M     241205     5.41      5.412        FIJA

    41135     S     201210     1.37      1.37375      UDIBonos

    41135     M     421113     6.58      6.5811       FIJA

    41135     M     310529     6.27      6.27175      FIJA

    y a ésta consulta le quiero pegar una columna mas llamada precio

    pero precio se calcula de esas mismas columnas, la cual la está dentro de un stored procedure muy complejo

    el stored es el siguiente:  

                                   FECHA  TV   SERIE   TASA   TARFICA

    EXECdbo.tCIA_GeneraParametros 41135 ,'M','241205',5.56 , 5.56655

    ESE STORED REGRESA LO SIGUIENTE:

    precioMin           |   precioMax        |   DxV       |  UDI                   

    ---------------------  ---------------------- ----------- ----

    169.18321294        |   169.60967945     |   4496      |  0                     

    Entonces, quiero tomar el PrecioMin de ese resultado y pegarlo en la primera consulta

    ojalá me haya explicado jeje


    saludos

    martes, 14 de agosto de 2012 14:17
  • FECHA     TV    SERIE      TASA      TARIFA       INSTRUMENTO2
    --------- ----- ---------- --------- ------------ ------------
    41135     M     241205     5.41      5.41375      FIJA
    41135     M     241205     5.42      5.422        FIJA
    41135     M     220609     5.34      5.3422       FIJA
    41135     M     241205     5.41      5.412        FIJA
    41135     S     201210     1.37      1.37375      UDIBonos
    41135     M     421113     6.58      6.5811       FIJA
    41135     M     310529     6.27      6.27175      FIJA
    

                                   FECHA  TV   SERIE   TASA   TARFICA

    EXECdbo.tCIA_GeneraParametros 41135 ,'M','241205',5.56 5.56655

    precioMin           |   precioMax        |   DxV       |  UDI                   
    ---------------------  ---------------------- ----------- ----
    169.18321294        |   169.60967945     |   4496      |  0                     
    


    saludos

    martes, 14 de agosto de 2012 14:21
  • en tu procedimiento dbo.tCIA_GeneraParametros  solo haces calculos matematicos ? o que tiene tu procedimiento( si puedes mostrarnos tmb tu procedimiento) ? o cual es la razon por la cual no la puedas meter en una función ? porque creo que es lo que hace falta :)


    martes, 14 de agosto de 2012 14:33
  • Es un stored complejo, utiliza instrucciones que no permiten ejecutarse dentro de una función

    es un procedimiento viejo y además contiene como 500 líneas, lo herede  =(

    entonces, no tiene caso ir por alli  =(

    si lo pudiera meter en una función, ya lo habría resuelto !!! jijiji

    intenté meter ese stored en una función y obtener el valor de PrecioMin como escalar

    pero las mugres funciones no me lo permiten, me restringen como lo mencioné anteriormente

    tal vez, se tenga que hacer de otra manera, pero no lo sé como


    saludos

    martes, 14 de agosto de 2012 14:36
  • Mmm pues entonces como lo veo, no te queda más que meter tu primera consulta en un CURSOR, y vayas leyendo los datos de este CURSOR para pasarlos como parametros a tu procedimiento, una vez obtenido el resultado de cada registro de tu CURSOR, metes tus parametros y tu resultado en una tabla temporal, CTE y al terminar tu CURSOR, le haces un SELECT * FROM a tu CTE.

    O si me equivoco me corrigen, pero revisa que tanto pudieras afectar tu rendimiento.

    martes, 14 de agosto de 2012 14:57
  • Don Omar:

    Usted puede ejecutar todo eso en un lote T-SQL.  ¿Cuál es su interfase con SQL Server?  Si es SQL Server Management Studio, entonces simplemente escribe las siguientes instrucciones en un archivo .sql y lo ejecuta.  Si es ADO.net entonces puede ejecutar las mismas instrucciones usando un SqlCommand con el tipo en CommandType.Text (o como sea que se llame esta enumeración, que nunca recuerdo).

    Create Table #tmp
    (
        PrecioMin money
        , ...
    );
    
    Insert Into #tmp
    exec dbo.tCIA_GeneraParametros 41135 ,'M','241205',5.56 , 5.56655;
    
    Declare @val money;
    
    Select @val = PrecioMin From #tmp;
    
    Drop Table #tmp;
    
    Select
        @val As [PrecioMin]
        , ....
    From
        ...
    ;

    Ese último Select sería el Select que produciría su tabla final con el valor del SP repetido en todas las filas bajo el nombre PrecioMin.


    Jose R. MCP
    Code Samples

    martes, 14 de agosto de 2012 14:59
  • hacer un cursor, creo que tengo idea,

    crearía un while, y ahorita investigo como voy barriendo registro a registro,

    la segunda opción no le entendí muy bien,

    quise hacer algo muy parecido en ésta ultima opción, pero las funciones no permites inserts jiji

    a ver, guardo el archivo en un *.sql y

    ¿cómo lo ejecuto por lotes?


    saludos

    martes, 14 de agosto de 2012 15:07
  • Hola.

    No se entiende lo que pretendes realizar, si obtener un dato único para acoplarlo a otra sentencia, si llamar repetidas veces a un procedimiento almacenado, usando como parámetros de entrada el conjunto de resultados de esa consulta o alguna otra cosa. Vamos contestando a tus preguntas, pero nunca daremos con la respuesta porque siempre viene un matiz después que cambia totalmente el sentido de la misma. Si no, fíjate qué fue lo que preguntaste y el punto en el que estamos ahora.

    Nos pones en la tesitura de tener que suponer, averiguar y por tanto aportar ideas que seguramente no se ajusten a lo que buscas, con lo que la ayuda que podemos darte es infructuosa. Así que, por favor, lee el post fijo del foro "Ayúdanos a ayudarte" y facilítanos la información de una forma en que la entendamos, sin tratar de simplificar ni omitir información que puede ser relevante, esto es, scripts de estructuras de datos, scripts con ejemplos de inserción, resultado esperado y sentencia que tienes hasta el momento, así como cualquier otro dato que creas que pueda ayudar, como la versión y edición de SQL Server.


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.com
    Sígueme en twitter en http://twitter.com/qwalgrande

    martes, 14 de agosto de 2012 15:38
    Moderador
  • Pues qwalgrande tiene un buen punto y sería genial una compilación de lo que está tratando de hacer.  Pero bueno, creo que finalmente ya entendí con eso que mencionó de CURSOR.  El procedimiento almacenado ese que devuelve una fila con precio mínimo tiene que correrse una vez por registro.

    Entonces sí:  Si no quiere tocar el procedimiento almacenado no le queda más que un cursor:

    Declare c Cursor For Select.... -- Aquí va el select primero que genera las filas a usar.
    
    --Declare una variable por cada campo de columna.
    --No sé bien los tipos de datos porque usted no muestra
    --la estructura de la tabla.  Corrija los tipos según
    --convenga.
    Declare @fecha int;
    Declare @TV nchar(1);
    Declare @serie int;
    Declare @tasa float;
    Declare @tarifa float;
    Declare @inst2 nvarchar(50);
    
    --Declare una variable de tabla para recoger los resultados:
    Declare @r Table
    (
        Fecha int
        , TV nchar(1)
        , Serie int
        , Tasa float
        , Tarifa float
        , inst2 nvarchar(50)
        , PrecioMin money
    );
    
    --Cree la tabla temporal según el formato de los datos devueltos por el
    --procedimiento almacenado.  Agregue una clave primaria.
    Create Table #tmp
    (
        ID int Not Null Identity(1, 1) Primary Key
        , PrecioMin money
        , ...
    );
    
    --Variable para extraer el resultado del procedimiento almacenado.
    Declare @pMin money;
    
    Open c;
    Fetch Next From c Into @fecha, @TV, @serie, @tasa, @tarifa, @inst2;
    While @@Fetch_Status = 0
    Begin
        Insert Into #tmp
    	exec dbo.tCIA_GeneraParametros @fecha, @TV, @serie, @tasa, @tarifa  -- CREO que esos son los valores correctos.
    	
    	Select Top 1 @pMin = PrecioMin From #tmp Order By ID Desc;
    	--Inserte ahora el resultado en la variable resultado:
    	Insert Into @r
    	Values (@fecha, @TV, @serie, @tasa, @tarifa, @inst2, @pMin);
        Fetch Next From c Into @fecha, @TV, @serie, @tasa, @tarifa, @inst2;
    End
    
    --Listo.  Muestre el resultado:
    Select * From @r;
    

    Si hubiera tenido la estructura de las tablas, el resultado hubiera podido ser obtenido mediante un INNER JOIN en vez de tener que usar una variable tipo Tabla (@r).


    Jose R. MCP
    Code Samples

    • Marcado como respuesta kakaroto2012 martes, 14 de agosto de 2012 17:40
    martes, 14 de agosto de 2012 16:56
  • bueno, es que en un principio, quería sacar el valor de un campo

    que entrega el stored Procedure, para meterlo en una función y llamar esa función en la consulta,

    como puedes ver, se me fué complicando la cosa, yo no iba a saber que la función me restringe demasiado

    No te das cuenta, pero a veces uno no sabe en los lios que uno se puede meter hasta que te das cuenta que estás bien metido jeje.

    de todas formas, agradezco a todos por su valiosisisimo tiempo y dedicación,

    quisiera darles puntos, jeje pero no se como hacerlo, en fin

    ya me voy de aquí, antes que me sigan regañando más!.

    saludos a todos


    saludos

    martes, 14 de agosto de 2012 17:34
  • Eres increíble hermano!!

    cuanto te agradezco!


    saludos

    martes, 14 de agosto de 2012 17:40