2016-04-25 16 views
1

私は2つの列を持つ表は、Prime_GuestIDとDup_GuestIDはGuestIDのとID(s)は、それが交換された(重複レコード)の間のリンクを示すために持っているSQLマージUPDATEステートメントでキー衝突を避け

今、私がしたいですフォーマットの他の数多くの関係テーブルを調べ、Dup_GuestIDの出現をPrime_GuestIDに更新します。

ただし、Prime_GuestIDに既に指定されたThingIDのエントリがある場合、代わりに関係テーブルからその行を削除する必要があります。

現在、私は次のスクリプトを使用していますが、ほとんどの場合、2つのDup_GuestIDが同じThingIDに対して同じPrime_GuestIDに更新されても失敗します。マージステートメントがすべての変更をキューに入れてから作成するので、クラッシュチェックでは変更が検出されないようです。

MERGE Thing_Relation AS t 
USING Guest_Relation AS g 
    ON t.GuestID = g.Dup_GuestID 
WHEN MATCHED AND EXISTS ( -- Clash Check here 
         select * 
         from Thing_Relation AS t2 
         where t2.ThingID = t.ThingID 
         and t2.GuestID = g.Prime_GuestID 
         ) 
THEN DELETE 
WHEN MATCHED 
THEN UPDATE SET t.GuestID = g.Prime_GuestID 

このマージの結果として生じる衝突をチェックするために、「一致して存在する」チェックを行うより良い方法はありますか?それともこの全部をやるより良い方法がありますか?

編集:まだ行が削除された存在101 | | 102 1に変更されます。ここで1は表

Thing_Relation   Guest_Relation 
ThingID | GuestID  Prime_GuestID | Dup_GuestID 
------------------  --------------------------- 
1  | 101      101 | 102 
1  | 102      107 | 104 
2  | 103      107 | 105 
3  | 104 
3  | 105 

Thing_Relation after merge 
ThingID | GuestID  
------------------  
1  | 101    
2  | 103 
3  | 107  

ためのいくつかのサンプルデータです。 2 | 103は影響を受けません 3 | 104は3 | 107に変更され、3 | 105も3 | 107に変更されますが、前回の更新はまだ発生していません。EXISTS節では取り上げられません。

+0

あなたの主な構文についてはわかりませんが、更新がnon deterministic.soであればマージは失敗しますが、それを解決しようとするのではなく、引き続き進んで更新したい場合は、派生テーブルを使用できます1つだけ一致する – TheGameiswar

+0

申し訳ありませんが、私はあなたのコメントを得ていません。行がテーブル内で衝突するようなものに更新された場合、その行を削除したいと思います。 しかし、マージステップで以前の更新によってクラッシュが生成された場合、私の「EXISTS」条件はそれを見つけられません。この問題を回避するために使用できるより良い条件がありますか? – skeletalmonkey

+0

あなたが話している2つのテーブルのいくつかのサンプルデータとテーブルスキーマを共有して、2つのテーブルの関係をよりよく理解できるようにしてください。 –

答えて

0

あなたはそうですが、MERGEはMERGEステートメント自体の変更をチェックしません。それはMERGEの基本的な財産です。いくつかのオプションがあります:

  1. 更新プログラムごとに競合がないかチェックし、重複する行を削除するUPDATEでTRIGGERを作成します。 OR
  2. は、UPDATEに2つの異なるステートメントを書き込み、後で重複するエントリに対して1つのDELETEを書き込むだけです。
関連する問題