2017-08-08 2 views
0

を削除し、更新キーは、私はエントリを削除し、重複キーエラーと

Table1 

    ColumnA ColumnB ColumnC ColumnD 
    A   1  A1  7/21/2017 
    B   2  B1  7/22/2017 
    C   3  C1  7/23/2017 

ユニークな組み合わせColumnAとColumnC

Table2 

    ColumnE ColumnF ColumnG 
    A  1  A1 
    A   2  A2 
    B   3  B1 
    B   2  B2 
    C   3  C1 
    C   1  C2 

それらを挿入し、その後重複している場合、私は、選択から行を挿入する必要がありますテーブル2からテーブル1に行を挿入する必要があります

Insert into table1 (columnA, columnB, ColumnC) select columnE, ColumnF, ColumnG from table2 

上記のクエリは、 plicateキーが挿入されますが、矛盾を作成してその行を挿入する行を削除するには が必要です。 最終出力は

Table 1 
ColumnA ColumnB ColumnC ColumnD 
    A  1  A1  08/08/2017 - deleted and added as conflict arised 
    A   2  A2  08/08/2017 
    B   3  B1  08/08/2017 -deleted and added as conflict arised 
    B   2  B2  08/08/2017 
    C   3  C1  08/08/2017  
    C   1  C2  08/08/2017 
+1

'MERGE':

そして、ここではMERGEとバージョンです。 'それが更新されたとき。 –

+0

このケースの具体例を教えてください。 – TechJump

+1

マージはまだ残念ながら遅いです。 UI(更新、挿入)シーケンスが最適ですが、DI(削除、挿入)シーケンスがおそらくより良いでしょう。 –

答えて

0

である必要があります。削除してから挿入する必要はありません。 ColumnD列(またはすべての非キー列)を更新し、Table2から新しい列を挿入するだけです。私は最初にUPDATEに行き、次にINSERTになるように発注するので、UPDATEは元の小さな行のセット(挿入前)で動作するようになります。ここでは、代わりにMERGEの、UPDATE-INSERT単なる古いです:

テーブル変数 @Conflicted
DECLARE 
    @Conflicted TABLE(
     ColumnA char(1), 
     ColumnB int, 
     ColumnC char(2), 
     ColumnD date 
    ) 

BEGIN TRAN 

UPDATE dst 
SET 
    dst.ColumnD = GETDATE() 
OUTPUT 
    deleted.ColumnA, 
    deleted.ColumnB, 
    deleted.ColumnC, 
    deleted.ColumnD 
INTO 
    @Conflicted 
FROM 
    Table1 AS dst 
    JOIN Table2 AS src 
    ON dst.ColumnA = src.ColumnE AND 
     dst.ColumnB = src.ColumnF AND 
     dst.ColumnC = src.ColumnG 

INSERT INTO Table1(
    ColumnA, 
    ColumnB, 
    ColumnC, 
    ColumnD 
) 
SELECT 
    t2.ColumnE, 
    t2.ColumnF, 
    t2.ColumnG, 
    GETDATE() 
FROM 
    Table2 AS t2 
WHERE 
    NOT EXISTS(SELECT * FROM Table1 WHERE ColumnA = t2.ColumnE AND ColumnB = t2.ColumnF AND ColumnC = t2.ColumnG) 

COMMIT TRAN 

今あなたがTable2から新しいものに置き換えられていTable1からすべての競合の行を持っています。

DECLARE 
    @Updated TABLE(
     ColumnA char(1), 
     ColumnB int, 
     ColumnC char(2), 
     ColumnD date, 
     Action nvarchar(10) 
    ) 

MERGE Table1 AS dst 
USING (
    SELECT * FROM Table2 
) as src 
ON dst.ColumnA = src.ColumnE AND 
    dst.ColumnB = src.ColumnF AND 
    dst.ColumnC = src.ColumnG 
WHEN NOT MATCHED THEN 
    INSERT(
     ColumnA, 
     ColumnB, 
     ColumnC, 
     ColumnD 
    ) VALUES (
     src.ColumnE, 
     src.ColumnF, 
     src.ColumnG, 
     GETDATE() 
    ) 
WHEN MATCHED THEN UPDATE 
    SET 
     dst.ColumnD = GETDATE() 
OUTPUT 
    deleted.ColumnA, 
    deleted.ColumnB, 
    deleted.ColumnC, 
    deleted.ColumnD, 
    $action AS action 
INTO 
    @Updated; 

SELECT * FROM @Updated WHERE Action = 'UPDATE' -- List replaced rows from the Table1