【问题标题】:Change the Table-Value Function to Inline from Multi-line将表值函数从多行更改为内联
【发布时间】:2019-03-15 05:52:12
【问题描述】:

我正在尝试更改表值函数以提高存储过程的性能,但我无法获得相同的结果。你能告诉我哪里出错了吗?

原文:

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

希望有人可以帮助我!

【问题讨论】:

  • 您必须在更改前后发布代码以及您的结果(预期和实际)。目前尚不清楚您的问题是什么以及您想要实现的目标

标签: sql tsql database-tuning


【解决方案1】:

您可以通过使用union all 创建一个大查询并将条件从if 表达式移动到内部查询的where 子句来更改它。此外,代替返回表中的Identity 列,将整个union all 包装在另一个查询中并选择row_number over(order by @@spid)(它返回任意原始数字,因为它是按常量排序的):

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-26
    • 2017-10-26
    • 2015-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多