当列不相等时,匹配更新时的SQL条件合并

时间:2017-09-26 20:54:27

标签: sql-server

我有一个名为SalesOrders的表。我将多个表中的数据合并到其中。在这个表中,我有一个名为Ack的列,当插入或更新行时,它将切换到'N'(我在C#代码中切换'Y')。我遇到的麻烦是当我运行查询时,我只希望Ack在某些内容发生变化时更改为“N”。我尝试在WHEN MATCHED语句中添加条件,但是当有更改时表永远不会更新。

MERGE QA.dbo.SalesOrders AS TARGET USING(SELECT SOD.ORDNUM_28 + 
LINNUM_28 + DELNUM_28 AS [SalesOrd], SOD.PRTNUM_28, PM.PMDES1_01,                                                                                                                                
SOD.CURDUE_28, SOD.DUEQTY_28, CPD.CUSTPRT_103, SOM.CUSTPO_27, 
CPD.UDFREF_103, CPD.PRTNUM_103,SOD.CreationDate, CM.EMAIL1_23, SOD.ORDNUM_28                                                                                                                              

FROM SO_Detail AS SOD FULL OUTER JOIN                                                                                                                               
Customer_Part_Data AS CPD ON SOD.PRTNUM_28 = CPD.PRTNUM_103 FULL OUTER JOIN                                                                                                                               
SO_Master AS SOM ON SOD.ORDNUM_28 = SOM.ORDNUM_27 FULL OUTER JOIN                                                                                                                              
Part_Master AS PM ON SOD.PRTNUM_28 = PM.PRTNUM_01 FULL OUTER JOIN                                                                                                                              
Customer_Master AS CM ON SOD.CUSTID_28 = CUSTID_23

WHERE (STATUS_28 = '3') AND (SOD.CreationDate > '09 / 14 / 2017') AND 
(CUSTPO_27 <> ' ') AND (SOM.STYPE_27 = 'CU')                                                                                                                               
AND (SOD.STK_28 NOT LIKE '%RMA%') AND (SOD.STYPE_28 = 'CU')) SOURCE

ON OrderNum = SOURCE.SalesOrd 
WHEN MATCHED AND PartNum <> SOURCE.PRTNUM_28 OR Description <> 
SOURCE.PMDES1_01 OR DueQty <> SOURCE.DUEQTY_28 OR CustPartNum <> 
SOURCE.CUSTPRT_103 OR CustPo <> SOURCE.CUSTPO_27 OR CustRev <> 
SOURCE.UDFREF_103 OR ShipDate <>   SOURCE.CURDUE_28 OR email <> 
SOURCE.EMAIL1_23  // This does not work

 THEN
 UPDATE       
 SET  PartNum = SOURCE.PRTNUM_28, Description = 
SOURCE.PMDES1_01, DueQty = SOURCE.DUEQTY_28, CustPartNum = 
SOURCE.CUSTPRT_103, CustPo = SOURCE.CUSTPO_27, CustRev =                          
SOURCE.UDFREF_103, ShipDate = SOURCE.CURDUE_28, email = SOURCE.EMAIL1_23, 
OrgDate = SOURCE.CreationDate, Ack = 'N' 

我在代码中注意到什么不起作用(WHEN MATCHED之后的所有东西) - 没有错误只是在更改某些内容时不会更新。如果我在AND之后删除代码,那么每次查询运行时都会更新 - 因此当没有真正改变时,将Ack更改为“N”。

2 个答案:

答案 0 :(得分:1)

通过一些基本的格式化,错误变得非常明显。匹配时,您在谓词中缺少括号。请注意,当这不是一个sql墙时,你实际上可以看到发生了什么。

MERGE QA.dbo.SalesOrders AS TARGET USING
(
    SELECT SOD.ORDNUM_28 + LINNUM_28 + DELNUM_28 AS [SalesOrd]
        , SOD.PRTNUM_28
        , PM.PMDES1_01
        , SOD.CURDUE_28
        , SOD.DUEQTY_28
        , CPD.CUSTPRT_103
        , SOM.CUSTPO_27
        , CPD.UDFREF_103
        , CPD.PRTNUM_103
        , SOD.CreationDate
        , CM.EMAIL1_23
        , SOD.ORDNUM_28                                                                                                                              
    FROM SO_Detail AS SOD 
    FULL OUTER JOIN Customer_Part_Data AS CPD ON SOD.PRTNUM_28 = CPD.PRTNUM_103 
    FULL OUTER JOIN SO_Master AS SOM ON SOD.ORDNUM_28 = SOM.ORDNUM_27 
    FULL OUTER JOIN Part_Master AS PM ON SOD.PRTNUM_28 = PM.PRTNUM_01 
    FULL OUTER JOIN Customer_Master AS CM ON SOD.CUSTID_28 = CUSTID_23
    WHERE STATUS_28 = '3'
        AND SOD.CreationDate > '09 / 14 / 2017' --Is this a date column? If so you need to use the ANSI standard YYYYmmdd
        AND CUSTPO_27 <> ' '
        AND SOM.STYPE_27 = 'CU'                                                                                                                               
        AND SOD.STK_28 NOT LIKE '%RMA%'
        AND SOD.STYPE_28 = 'CU'
) SOURCE

ON OrderNum = SOURCE.SalesOrd 
WHEN MATCHED 
AND 
( --you need this here
    PartNum <> SOURCE.PRTNUM_28 
    OR Description <> SOURCE.PMDES1_01 
    OR DueQty <> SOURCE.DUEQTY_28 
    OR CustPartNum <> SOURCE.CUSTPRT_103 
    OR CustPo <> SOURCE.CUSTPO_27 
    OR CustRev <> SOURCE.UDFREF_103 
    OR ShipDate <> SOURCE.CURDUE_28 
    OR email <> SOURCE.EMAIL1_23  --// This does not work
) --Without the parenthesis the update would fire when ANY of those conditions are met
THEN
UPDATE       
SET PartNum = SOURCE.PRTNUM_28
    , Description = SOURCE.PMDES1_01
    , DueQty = SOURCE.DUEQTY_28
    , CustPartNum = SOURCE.CUSTPRT_103
    , CustPo = SOURCE.CUSTPO_27
    , CustRev = SOURCE.UDFREF_103
    , ShipDate = SOURCE.CURDUE_28
    , email = SOURCE.EMAIL1_23
    , OrgDate = SOURCE.CreationDate
    , Ack = 'N' 

答案 1 :(得分:0)

想出来:我的问题是,我是不理解NULL的受害者。这里有很好的讨论:Why does NULL = NULL evaluate to false in SQL server。基本上,条件无法触发更新,因为他们根本不知道答案(NULL)。我需要更新我的INSERT以包含一个CASE,所以如果值为NULL - 插入''(一个空白),所以我的条件将有一些东西要比较。