【问题标题】:sp_executesql vs user defined scalar functionsp_executesql vs 用户定义的标量函数
【发布时间】:2013-08-21 12:27:24
【问题描述】:

在下表中,我存储了一些这样的条件:

然后,一般来说,在第二张表中,我有以下记录:

我需要的是使用正确的条件比较这些值并存储结果(假设“0”表示假,“1”表示真在附加列中)。

我将在存储过程中执行此操作,基本上我将比较几条到数百条记录。

什么可能的解决方案是使用 sp_executesql 为每一行构建动态语句,另一种是创建我自己的标量函数并使用交叉应用为每个行调用它。

谁能告诉我哪种方法更有效?

注意:我知道回答这个问题的最好方法是制作两个解决方案并进行测试,但我希望可以根据缓存和 SQL 内部优化等其他内容来回答这个问题,这将节省了我很多时间,因为这只是更大问题的一部分。

【问题讨论】:

    标签: tsql sql-server-2012 user-defined-functions cross-apply sp-executesql


    【解决方案1】:

    我认为在这种情况下不需要使用sp_executesql。您可以在一条语句中一次获取所有记录的结果:

    select Result = case
        when ct.Abbreviation='=' and t.ValueOne=t.ValueTwo then 1
        when ct.Abbreviation='>' and t.ValueOne>t.ValueTwo then 1
        when ct.Abbreviation='>=' and t.ValueOne>=t.ValueTwo then 1
        when ct.Abbreviation='<=' and t.ValueOne<=t.ValueTwo then 1
        when ct.Abbreviation='<>' and t.ValueOne<>t.ValueTwo then 1
        when ct.Abbreviation='<' and t.ValueOne<t.ValueTwo then 1
        else 0 end
    from YourTable t
        join ConditionType ct on ct.ID = t.ConditionTypeID
    

    并使用以下内容更新其他列:

    ;with cte as (
        select t.AdditionalColumn, Result = case
            when ct.Abbreviation='=' and t.ValueOne=t.ValueTwo then 1
            when ct.Abbreviation='>' and t.ValueOne>t.ValueTwo then 1
            when ct.Abbreviation='>=' and t.ValueOne>=t.ValueTwo then 1
            when ct.Abbreviation='<=' and t.ValueOne<=t.ValueTwo then 1
            when ct.Abbreviation='<>' and t.ValueOne<>t.ValueTwo then 1
            when ct.Abbreviation='<' and t.ValueOne<t.ValueTwo then 1
            else 0 end
        from YourTable t
            join ConditionType ct on ct.ID = t.ConditionTypeID
    )
    update cte
    set AdditionalColumn = Result
    

    如果上述逻辑应该应用于许多地方,而不仅仅是一张桌子,那么是的,你可能会考虑功能。虽然我宁愿使用 inline table-valued 函数(而不是 scalar),因为使用用户定义的标量函数(调用和返回,以及要处理的行越多,浪费的时间就越多)。

    create function ftComparison
    (
        @v1 float,
        @v2 float,
        @cType int
    )
    returns table
    as return
        select
            Result = case
                when ct.Abbreviation='=' and @v1=@v2 then 1
                when ct.Abbreviation='>' and @v1>@v2 then 1
                when ct.Abbreviation='>=' and @v1>=@v2 then 1
                when ct.Abbreviation='<=' and @v1<=@v2 then 1
                when ct.Abbreviation='<>' and @v1<>@v2 then 1
                when ct.Abbreviation='<' and @v1<@v2 then 1
                else 0
            end
        from ConditionType ct
        where ct.ID = @cType
    

    然后可以应用为:

    select f.Result
    from YourTable t
        cross apply ftComparison(ValueOne, ValueTwo, t.ConditionTypeID) f
    

    select f.Result
    from YourAnotherTable t
        cross apply ftComparison(SomeValueColumn, SomeOtherValueColumn, @someConditionType) f
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-15
      • 2020-06-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-28
      • 2016-02-18
      相关资源
      最近更新 更多