3

通常、これらの行が最初にターゲット テーブルに入力される方法は、まばらな数の列に大部分がテキスト データで入力され、残りの列は NULL に設定されます。後続のパスでは、新しいデータが既存の既知 (null 以外) および不明 (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 

ステートメントの更新部分の下にある != を <> に置き換えてみました。同じ結果です。これは、可能性のある (可能性の高い) null 値と文字列の比較に関連している必要があります。おそらく別の null でしょうか? とにかく、私はすべてのSQLマニアにこれを解くよう呼びかけています。

4

3 に答える 3

3

また、 NULLIF()関数でオプションを使用することもできます。

2 つの式が等しくない場合、NULLIF は最初の式を返します。式が等しい場合、NULLIF は最初の式の型の null 値を返します。

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

私が質問を理解しているので、あなたはエミュレートする表現を探しています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 に答える
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、空の文字列と同じ意味で問題ないことを前提としています (これは適切ではない可能性があります)。

比較に関するこの BOL 記事をご覧ください。NULL

于 2013-03-12T22:18:32.253 に答える