2017-08-08 70 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 

上述查詢得到衝突說du插入了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'。 「什麼時候匹配更新」。 –

+0

你能否提供這個案例的一些具體例子? – TechJump

+1

合併仍然不幸很慢。 DI(刪除,然後插入)序列可能會更好,但UI(更新,然後插入)序列將是最好的。 –

回答

0

您不必刪除然後插入。只需更新ColumnD列(或所有非關鍵列)並從Table2插入新列。我會訂購報表,首先執行UPDATE,然後INSERT,以便UPDATE可以在較小的原始行集上(插入前)工作。在這兒,而不是MERGE,只是普通的老UPDATE-INSERT

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 

在表變量@Conflicted現在你必須從Table1已替換爲Table2新的所有衝突行。

這裏是MERGE版本:

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