Tengo un par de vistas que obtienen ciertos registros de la BD's, pero los obtengo por filas y los requiero por columnas, así que implementé un SP que traspone a mis necesidades la información, pero el problema es que se tarda mucho. Para una consulta que regresa 100 registros, se tarda casi 2 minutos para ejecutar el SP.
El detalle es que hago varias concatenaciones por que necesito la información con ciertas características:
1) Debe haber 4 columnas: M, P, T y O adicionales a la de la llave (NoParte). Las 3 columnas primeras son 'unicas y la 4a es el acumulado del resto de los valores del campo "Almacen"
2) La vista puede regresarme 1 o más registros pertenecientes a x número de almacenes, a veces 1 o 2 almacenes, a veces más y en cualquier orden.
Para forzar a que siempre se formen las 4 columnas en orden, hago acumulados y concatenaciones.
Si alguien pudiera darme una idea de como optimizar el SP, se lo agradecería mucho, el SP es el siguiente:
Código:
CREATE PROCEDURE sResumen_Assort_Inventario
AS
BEGIN
DECLARE @NoParte varchar(10)
DECLARE @NomAlmacen VARCHAR(50)
DECLARE @Valor float
DECLARE @Suma float
DECLARE @AlmacenM float
DECLARE @AlmacenP float
DECLARE @AlmacenT float
DECLARE @Count INT
DECLARE @GrantCount INT
DECLARE @Select VARCHAR(8000)
DECLARE @GrantSelect VARCHAR(8000)
DECLARE @CadAlmacenes VARCHAR(10)
DECLARE @Salida VARCHAR(8000)
DECLARE @IDAlmacen CHAR(1)
SET @GrantCount = 0
SET @GrantSelect = ''
DECLARE NumerosDeParte CURSOR SCROLL FOR
(SELECT NoParte
FROM vw_Assort_Esp
GROUP BY NoParte)
OPEN NumerosDeParte
FETCH FIRST FROM NumerosDeParte INTO @NoParte
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE CurExistencias CURSOR SCROLL FOR
(SELECT Almacen, TonTotales, NoParte
FROM vw_Assort_Inv
WHERE NoParte = @NoParte)
SET @Select = ''
SET @Count = 0
SET @CadAlmacenes = ''
SET @Suma = 0
SET @AlmacenM = 0
SET @AlmacenP = 0
SET @AlmacenT = 0
OPEN CurExistencias
FETCH FIRST FROM CurExistencias INTO @NomAlmacen, @Valor, @NoParte
WHILE @@FETCH_STATUS = 0
BEGIN
SET @Count = @Count + 1
SET @NomAlmacen = RTRIM(LTRIM(@NomAlmacen))
IF @Count = 1
SET @Select = @Select + ' SELECT NoParte=''' + RTRIM(LTRIM(@NoParte))+''''
IF @NomAlmacen='M' OR @NomAlmacen='P' OR @NomAlmacen='T'
BEGIN
IF @NomAlmacen = 'M'
SET @AlmacenM = @Valor
IF @NomAlmacen = 'P'
SET @AlmacenP = @Valor
IF @NomAlmacen = 'T'
SET @AlmacenT = @Valor
END
ELSE
SET @Suma = @Suma + @Valor
SET @CadAlmacenes = @CadAlmacenes + @NomAlmacen
FETCH NEXT FROM CurExistencias INTO @NomAlmacen, @Valor, @NoParte
END
CLOSE CurExistencias
DEALLOCATE CurExistencias
SET @Salida = ''
DECLARE CurAlmacenes CURSOR SCROLL FOR (SELECT Almacen FROM Almacenes WHERE Tipo='E')
OPEN CurAlmacenes
FETCH FIRST FROM CurAlmacenes INTO @IDAlmacen
WHILE @@FETCH_STATUS = 0
BEGIN
IF CHARINDEX(@IDAlmacen, @CadAlmacenes)=0
BEGIN
IF RTRIM(LTRIM(@IDAlmacen))='M' OR RTRIM(LTRIM(@IDAlmacen))='P' OR RTRIM(LTRIM(@IDAlmacen))='T'
BEGIN
SET @Salida = @Salida + ', ' + @IDAlmacen + '= ''0'''
END
END
ELSE
BEGIN
IF @IDAlmacen = 'M'
SET @Salida = @Salida + ',M= '''+CONVERT(VARCHAR,@AlmacenM)+''''
IF @IDAlmacen = 'P'
SET @Salida = @Salida + ',P= '''+CONVERT(VARCHAR,@AlmacenP)+''''
IF @IDAlmacen = 'T'
SET @Salida = @Salida + ',T= '''+CONVERT(VARCHAR,@AlmacenT)+''''
END
FETCH NEXT FROM CurAlmacenes INTO @IDAlmacen
END
CLOSE CurAlmacenes
DEALLOCATE CurAlmacenes
IF @Suma > 0
SET @Salida = @Salida + ', NG= '''+CONVERT(VARCHAR,@Suma)+''''
ELSE
SET @Salida = @Salida + ', NG= ''0'''
IF @Count=0
SET @Select = @Select + ' SELECT NoParte=''' + RTRIM(LTRIM(CONVERT(VARCHAR,@NoParte)))+'''' + @Salida
ELSE
SET @Select = @Select + @Salida
SET @Select = @Select + CHAR(13)
SET @GrantCount = @GrantCount + 1
IF @GrantCount = 1
SET @GrantSelect = @Select
ELSE
SET @GrantSelect = @GrantSelect + CHAR(13) + ' UNION ' + CHAR(13)+ @Select
FETCH NEXT FROM NumerosDeParte INTO @NoParte
END
PRINT(@GrantSelect)
EXEC(@GrantSelect)
CLOSE NumerosDeParte
DEALLOCATE NumerosDeParte
END
GO