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