1

В таблице ниже я хранить некоторые условия, как это:sp_executesql против определенного пользователя скалярной функции

enter image description here

Затем, как правило, в второй таблице, я имеющая следующие записи:

enter image description here

и мне нужно сравнить эти значения, используя правильное условие и сохранить результат (допустим, «0» для false и «1» для true в дополнительной колонке).

Я собираюсь сделать это в магазине, и в основном я собираюсь сравнить от нескольких до сотен записей.

Какое из возможных решений заключается в использовании sp_executesql для каждой строки, создающей динамические операторы, а другое - для создания моей собственной скалярной функции и для вызова ее для обычной строки с использованием cross apply.

Может ли кто-нибудь сказать, что является более эффективным способом?

Примечание: Я знаю, что лучший способ ответить на этот вопрос - сделать два решения и проверить, но я надеюсь, что на это можно ответить, основываясь на других вещах, таких как кэширование и внутренние оптимизации SQL и другие, что сэкономит мне много времени, потому что это только часть более серьезной проблемы.

ответ

2

В этом случае я не вижу необходимости использовать 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-value функция (не скаляр), из-за накладных расходов, наложенных с использованием определенных пользователем скалярных функций (для вызова и возврата, а также для большего количества строк, которые будут обрабатываться больше времени) ,

create function ftComparison 
(
    @v1 float, 
    @v2 float, 
    @cType int 
) 
returns table 
as return 
    select 
     Result = case 
      when ct.Abbreviation='=' and @[email protected] then 1 
      when ct.Abbreviation='>' and @v1>@v2 then 1 
      when ct.Abbreviation='>=' and @v1>[email protected] then 1 
      when ct.Abbreviation='<=' and @v1<[email protected] 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 

 Смежные вопросы

  • Нет связанных вопросов^_^