Almacenar resultados de procedimiento almacenado en tabla temporal

publicado por: Anonymous

Transfondo

Tengo un procedimiento almacenado en una base de datos en SQL Server 20121 que obtiene el promedio de algunos valores. Este procedimiento almacenado recibe como parámetros dos (2) valores de tipo int.

Ejemplo:

  • IdFuncionario
  • IdProceso

1 Es la versión del gestor de base de datos que tengo en el equipo de desarrollo, pero es posible que esta base de datos esté instalada en una versión diferente.


Problema

Ya que el procedimiento almacenado también debe permitir obtener el promedio de todos los funcionarios, quisiera crear un nuevo procedimiento para ejecutarlo de esta manera:

Código de consulta de prueba:

-- Crear tabla temporal. Código adaptado de 
-- https://stackoverflow.com/a/654418/4092887
CREATE TABLE #tmpBus
(
   IDFUNCIONARIO NUMERIC (12, 0),
   NOMBRE VARCHAR(100),
   CAL_1 FLOAT,
   CAL_2 FLOAT
);

-- Usando CTE "Common Table Expressions", recorrer la tabla "Funcionarios"
-- e invocar el procedimiento almacenado para ir guardando los resultados
-- en la tabla temporal "#tmpBus".
WITH CTE_func
AS
(
    SELECT FUNC.IdFuncionario, FUNC.Nombre, 1 AS IdProceso
    FROM Funcionario AS FUNC
)
SELECT temp.Nombre, EXEC SP_PromedioReporte temp.IdFuncionario, temp.IdProceso
FROM CTE_func AS temp

-- Retornar los valores almacenados en la tabla temporal.
SELECT *
FROM #tmpBus

Donde SP_PromedioReporte es el procedimiento almenado que calcula el promedio según el empleado y proceso especificado; devolviendo dos columnas:

---------------------------
| Promedio 1 | Promedio 2 |
---------------------------

Los resultados que espero obtener son similares a esta tabla:

---------------------------------------
| Nombre    | Promedio 1 | Promedio 2 |
---------------------------------------
|Alfonso    | 10         | 85         |
---------------------------------------
|María      | 12         | 38         |
---------------------------------------
|Jaime      | 16         | 63         |
---------------------------------------
|Rodrigo    | 20         | 69         |
---------------------------------------
|Laura      | 18         | 49         |
---------------------------------------

Buscando en otras preguntas y respuestas en Stack Overflow, me encontrado esta respuesta donde básicamente se crea una tabla temporal para almacenar los resultados del procedimiento almacenado, pero no logro ajustar la consulta para que, al recorrer todos los funcionarios (de la tabla Funcionarios), se ejecute y se guarde en la tabla temporal.

Los errores que tengo son de sintaxis y reconozco que no tengo idea de cómo puedo realizar esta funcionalidad.

¿Cómo puedo generar un procedimiento almacenado que a su vez llame a otro procedimiento almacenado “en este caso, a SP_PromedioReporte” según lo explico en esta pregunta? ver código de consulta de prueba:.

NOTA: Para este caso, estoy buscando una solución puramente en SQL Server, ya que, por lógica, podría consultar primero la tabla “Funcionarios” y hacer un ciclo para ir llamando al procedimiento almacenado y procesar todo “por back-end”, sin embargo, en el proyecto en el que estoy involucrado, se busca que toda la lógica se aplique en procedimientos almacenados.

solución

No es posible mandar llamar a un procedimiento almacenado directamente desde una consulta, pero lo que sí puedes hacer es mandarlo llamar a través de una función, es decir, en lugar de que SP_PromedioReporte sea un procedimiento almacenado, éste sea una función, para lo cual quedaría algo como esto:

CREATE FUNCTION dbo.FN_PromedioReporte (@IdFuncionario INT, @IdProceso INT)
RETURNS DECIMAL(18,6)
AS BEGIN
    DECLARE @resultado DECIMAL(18,6)

    --Código de ejemplo para regresar un resultado, yo puse una división para simular el valor de retorno
    --Aquí va la lógica de lo que anteriormente era un Stored Procedure
    SET @resultado = @IdFuncionario / @IdProceso

    RETURN @Resultado
END

Con esto, ya lo podrás mandar llamar en tu consulta directamente con dbo.FN_PromedioReporte(temp.IdFuncionario, temp.IdProceso):

....
SELECT temp.Nombre, dbo.FN_PromedioReporte(temp.IdFuncionario, temp.IdProceso)
FROM CTE_func AS temp
....

Aquí puedes ver la demostración

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *