0

I'm trying to change a Table-Valued Function to improve the performance of a Stored Procedure but I can't get the same result. Can you tell me where I'm going wrong?

Original:

create FUNCTION [dbo].[fun_eess1] (
@institucion int ,
@disa int,
@red int,
@mred int) RETURNS @tbl TABLE (idlista [int] IDENTITY, institucion [int], disa [int], red [int], mred [int], establecimiento varchar(10)) AS BEGIN
IF (@institucion=1) -- First Condition */ where @institucion=1 then UNION ALL
BEGIN
    INSERT INTO @tbl ([institucion], [disa], [red], [mred], [establecimiento])
    SELECT DISTINCT [c_institucion], [c_disa], [c_red], [c_microred], [codrenae] FROM [dbo].[RENAE]
    WHERE 

    [c_institucion]=@institucion AND [c_disa]=(CASE @disa WHEN -1 THEN [c_disa] ELSE @disa END)
    AND [c_red]=(CASE @red WHEN -1 THEN [c_red] ELSE @red END)
    AND [c_microred]=(CASE @mred WHEN -1 THEN [c_microred] ELSE @mred END)
END  ELSE
BEGIN
IF (@institucion=15) -- Second Condition */ where @institucion=15 then UNION ALL
BEGIN
    INSERT INTO @tbl ([institucion], [disa], [red], [mred], [establecimiento])
    SELECT DISTINCT [c_institucion], [c_disa], [c_red], [c_microred], [codrenae] FROM [dbo].[RENAE]
    WHERE [c_institucion]='1' AND [c_disa]=(CASE @disa WHEN -1 THEN [c_disa] ELSE @disa END)
    AND [c_red]=(CASE @red WHEN -1 THEN [c_red] ELSE @red END)
    AND [c_microred]=(CASE @mred WHEN -1 THEN [c_microred] ELSE @mred END)

    INSERT INTO @tbl ([institucion], [disa], [red], [mred], [establecimiento])
    SELECT [org].[CodigoOrganizacion], [di].[iddisa], [r].[idred], [mi].[idmred], CAST ([es].[idestablecimiento] AS varchar) FROM [dbo].[Establecimientos] es
    INNER JOIN [dbo].[microred] mi ON [mi].[idmred]=[es].[microred]
    INNER JOIN [dbo].[Red] r ON [mi].[red] = [r].[idred]
    INNER JOIN [dbo].[Disa] di ON [r].[disa] = [di].[iddisa]
    INNER JOIN [dbo].[Organizacion] org ON [di].[institucion] = [org].[CodigoOrganizacion]
    WHERE [org].[CodigoOrganizacion] in ('2','3','4','5','6','13') AND [di].[iddisa]=(case @disa when -1 then [iddisa] else @disa end) AND [r].[idred]=(case @red when -1 then [idred] else @red end)  AND [mi].[idmred]=(case @mred when -1 then [idmred] else @mred end)
END
ELSE
BEGIN  -- Third Condition? */ where @institucion is not (1,15) then UNION ALL
    INSERT INTO @tbl ([institucion], [disa], [red], [mred], [establecimiento])
    SELECT [org].[CodigoOrganizacion], [di].[iddisa], [r].[idred], [mi].[idmred], CAST ([es].[idestablecimiento] AS varchar) FROM [dbo].[Establecimientos] es
    INNER JOIN [dbo].[microred] mi ON [mi].[idmred]=[es].[microred]
    INNER JOIN [dbo].[Red] r ON [mi].[red] = [r].[idred]
    INNER JOIN [dbo].[Disa] di ON [r].[disa] = [di].[iddisa]
    INNER JOIN [dbo].[Organizacion] org ON [di].[institucion] = [org].[CodigoOrganizacion]
    WHERE [org].[CodigoOrganizacion]=@institucion AND [di].[iddisa]=(case @disa when -1 then [iddisa] else @disa end) AND [r].[idred]=(case @red when -1 then [idred] else @red end)  AND [mi].[idmred]=(case @mred when -1 then [idmred] else @mred end) 
END END

Hope someone can help me!

AS Mackay
  • 2,831
  • 9
  • 19
  • 25
  • You have to post code before and after changes and your results (expected and actual). It's unclear what's your issue and what you're trying to achieve – barbsan Mar 15 '19 at 09:55

1 Answers1

1

You can change it by creating one big query using union all, and moving the conditions from the if expressions to the where clauses of the inner queries. Also, instead of the Identity column in the return table, wrap the entire union all in another query and select row_number over(order by @@spid) (which returns an arbitrary raw number since it's ordered by a constant):

CREATE FUNCTION [dbo].[fun_eess1] 
(
    @institucion int ,
    @disa int,
    @red int,
    @mred int
)

RETURNS TABLE 

AS BEGIN

    SELECT ROW_NUMBER() OVER(ORDER BY @@SPID) As idlista, *
    FROM (
        SELECT DISTINCT 
                [c_institucion] As [institucion], 
                [c_disa] As [disa], 
                [c_red] AS [red], 
                [c_microred] AS [mred], 
                [codrenae] AS [establecimiento]
        FROM [dbo].[RENAE]
        WHERE @institucion=1 -- First condition
        AND [c_institucion]=@institucion 
        AND [c_disa] = CASE @disa WHEN -1 THEN [c_disa] ELSE @disa END
        AND [c_red] = CASE @red WHEN -1 THEN [c_red] ELSE @red END
        AND [c_microred] = CASE @mred WHEN -1 THEN [c_microred] ELSE @mred END

        UNION ALL

        SELECT DISTINCT [c_institucion], [c_disa], [c_red], [c_microred], [codrenae] 
        FROM [dbo].[RENAE]
        WHERE @institucion=15 -- Second condition
        AND [c_institucion]='1' 
        AND [c_disa] = CASE @disa WHEN -1 THEN [c_disa] ELSE @disa END
        AND [c_red] = CASE @red WHEN -1 THEN [c_red] ELSE @red END
        AND [c_microred] = CASE @mred WHEN -1 THEN [c_microred] ELSE @mred END

        UNION ALL

        SELECT [org].[CodigoOrganizacion], [di].[iddisa], [r].[idred], [mi].[idmred], CAST ([es].[idestablecimiento] AS varchar) 
        FROM [dbo].[Establecimientos] es
        INNER JOIN [dbo].[microred] mi ON [mi].[idmred]=[es].[microred]
        INNER JOIN [dbo].[Red] r ON [mi].[red] = [r].[idred]
        INNER JOIN [dbo].[Disa] di ON [r].[disa] = [di].[iddisa]
        INNER JOIN [dbo].[Organizacion] org ON [di].[institucion] = [org].[CodigoOrganizacion]
        WHERE 
        (
            (
                @institucion=15 -- Second condition
                AND [org].[CodigoOrganizacion] in ('2','3','4','5','6','13')
            )
            OR 
            (
                @institucion NOT IN(1, 15) -- Third condition
                AND [org].[CodigoOrganizacion] = @institucion
            )
        )
        AND [di].[iddisa] = case @disa when -1 then [iddisa] else @disa end  
        AND [r].[idred] = case @red when -1 then [idred] else @red end 
        AND [mi].[idmred]= case @mred when -1 then [idmred] else @mred end

    )

END
Zohar Peled
  • 79,642
  • 10
  • 69
  • 121