3

这些行通常第一次进入目标表的方式是使用少数列填充大部分文本数据,其余列设置为 NULL。在随后的传递中,新数据填充现有的已知(非空)和未知(空)数据。我已经确定新数据(#pld)确实包含不同的数据。数据似乎没有变化。这是我所拥有的:

  BEGIN TRANSACTION

  BEGIN TRY


  MERGE INTO [metro].listings AS metroList
    USING #pld as listnew
      ON metroList.id = listnew.id
      AND metroList.sid = listnew.sid
      WHEN MATCHED AND (
        metroList.User != listnew.User
         or metroList.Email != listnew.Email
         or metroList.LocName != listnew.LocName
   ) THEN
   UPDATE SET
    metroList.User = listnew.User,
    metroList.Email = listnew.Email,
    metroList.LocName = listnew.LocName,
   WHEN NOT MATCHED THEN
  INSERT
   ( User,
     Email,
     LocName
   )
   VALUES
   (
     listnew.User,
     listnew.Email,
      listnew.LocName
    );

  COMMIT TRANSACTION

 END TRY


 IF @@TRANCOUNT > 0
    ROLLBACK TRANSACTION;

 END CATCH 

我尝试将 != 替换为语句的更新部分下的 <> 。结果相同。这必须与一个可能的(可能的)空值与字符串的比较有关——甚至可能是另一个空值?无论如何,我呼吁所有的 sql-geeks 来解决这个问题。

4

3 回答 3

3

您也可以将选项与NULLIF()函数一起使用。

如果两个表达式不相等,则 NULLIF 返回第一个表达式。如果表达式相等,则 NULLIF 返回第一个表达式类型的空值。

WHEN MATCHED AND (
                  NULLIF(ISNULL(metroList.[User],''), listnew.[User]) IS NOT NULL
                    OR NULLIF(ISNULL(metroList.Email, ''), listnew.Email) IS NOT NULL
                    OR NULLIF(ISNULL(metroList.LocName, ''), listnew.LocName) IS NOT NULL
                  )
THEN
于 2013-03-12T22:35:59.760 回答
2

NULL空字符串比较将不起作用。

如果任何一方都可以NULL,您可以执行以下操作:

WHEN MATCHED AND (
        COALESCE(metroList.User, '')    <> COALESCE(listnew.User, '')
     or COALESCE(metroList.Email, '')   <> COALESCE(listnew.Email, '')
     or COALESCE(metroList.LocName, '') <> COALESCE(listnew.LocName, '')
   ) THEN

当然,这假设您可以接受与NULL空字符串相同的含义(这可能不合适)。

看看这篇关于NULL比较的 BOL 文章。

于 2013-03-12T22:18:32.253 回答
2

据我了解,您正在寻找一个模仿IS DISTINCT FROM.

那么您接受的答案不正确

WITH metroList([User])
     AS (SELECT CAST(NULL AS VARCHAR(10))),
     listnew([User])
     AS (SELECT 'Foo')
SELECT *
FROM   metroList
       JOIN listnew
         ON NULLIF(metroList.[User], listnew.[User]) IS NOT NULL 

返回零行。尽管比较的值是NULLFoo

我将使用本文中的技术:未记录的查询计划:平等比较

WHEN MATCHED AND EXISTS (
                         SELECT  metroList.[User], metroList.Email,metroList.LocName
                         EXCEPT
                         SELECT  listnew.[User], listnew.Email,listnew.LocName
                         )    
于 2013-03-13T07:22:28.337 回答