避免在MERGE和UPDATE语句中多次调用标量函数

时间:2018-12-26 13:21:11

标签: sql sql-server

我想调用多次返回标量的函数。 如何在MERGE语句中做到这一点?

我的代码:

MERGE [dbo].MyTable m
USING (select * from Table2 edbl 
where IsRowError = 0) edbTable
on  edbTable.Filed1 = m.Filed1
WHEN MATCHED THEN UPDATE SET 
m.Filed2 = case when dbo.func1(edbTable.Filed7) = 1 then 1 
                when dbo.func1(edbTable.Filed7) = 0 then 1
                else 0 end,
m.Filed3 = case when dbo.func1(edbTable.Filed7) = 0 then 0 end,
m.Filed4 = case when dbo.func1(edbTable.Filed7) = 0 then 3 end,
m.Filed5 = case when dbo.func1(edbTable.Filed7) = 0 then 9 else 5 end,
m.Filed6 = getdate();

我也想在UPDATE语句中这样做:

UPDATE md
set Filed1 = case when dbo.func1(edbl.Filed7) = 0  then 0 end,
    Filed5 = case when dbo.func1(edbTable.Filed7)=0 then 9 else 5 end,
    Filed6 = getdate()
from  Table2 edbl
    join Table3 m on edbl.Filed2= m.Filed2
    join Table4 md on m.Filed3=md.Filed3
    join Table5 mb on md.Filed4 = mb.Filed4
where IsRowError = 0

3 个答案:

答案 0 :(得分:2)

您可以在子查询中执行此操作:

MERGE [dbo].MyTable m
USING (select edbl.*, dbo.func1(edbTable.Filed7) as func1
       from Table2 edbl 
       where IsRowError = 0
      ) edbTable
      on  edbTable.Filed1 = m.Filed1
WHEN MATCHED THEN UPDATE SET 
    m.Filed2 = (case when func1 = 1 then 1 
                     when func1 = 0 then 1
                     else 0
                end),
    m.Filed3 = case when func1 = 0 then 0 end,
    m.Filed4 = case when func1 = 0 then 3 end,
    m.Filed5 = case when func1 = 0 then 9 else 5 end,
    m.Filed6 = getdate();

但是,目前尚不清楚这是一次大胜利。如果大多数行不匹配,那么这可能不是一个很大的改进。

答案 1 :(得分:1)

您可以在USING部分进行一次操作:

MERGE [dbo].MyTable m
USING (select *, dbo.func1(Filed7) AS f from Table2 edbl 
where IsRowError = 0) edbTable
on  edbTable.Filed1 = m.Filed1
WHEN MATCHED THEN UPDATE SET 
m.Filed2 = case when f = 1 then 1 
                when f = 0 then 1
                else 0 end,
m.Filed3 = case when f = 0 then 0 end,
m.Filed4 = case when f = 0 then 3 end,
m.Filed5 = case when f = 0 then 9 else 5 end,
m.Filed6 = getdate();

答案 2 :(得分:1)

您可以将APPLYUPDATE语句一起使用:

UPDATE md
     SET Filed1 = CASE WHEN fun = 0 THEN 0 END,
         Filed5 = CASE WHEN fun = 0 THEN 9 ELSE 5 END,
         Filed6 = getdate()
FROM Table2 edbl JOIN 
     Table3 m 
     ON edbl.Filed2 = m.Filed2 JOIN 
     Table4 md 
     ON m.Filed3 = md.Filed3 JOIN 
     Table5 mb 
     ON md.Filed4 = mb.Filed4 CROSS APPLY
     ( VALUES (dbo.func1(edbl.Filed7)) 
     ) edbl1(fun) 
where IsRowError = 0;