TSQL插入如果不存在

时间:2014-10-19 17:32:58

标签: sql sql-server tsql insert sql-server-2014

我试图将1.5M行从一个数据库复制到另一个数据库。我已经在SO上进行了很多搜索,但无法使其发挥作用。

源表有重复项(使用Src表中的Col1 + Col2),我需要确保没有重复项插入到新目标tabe中。这是我的SQL:

INSERT INTO DestDb.dbo.DestTable ([Col1], [Col2])   
SELECT [Col1], DATEADD(dd, DATEDIFF(dd, 0, [Col2]), 0)  
FROM dbo.SrcTable as Table1
WHERE NOT EXISTS (
                    SELECT 1
                    FROM DestDb.dbo.DestTable
                    WHERE DestDb.dbo.DestTable.Col1 = Table1.Col1
                        AND DATEDIFF(DAY, DestDb.dbo.DestTable.Col2, Table1.Col2) = 0
)

DestDb.dbo.DestTable的复合键为Col1 + Col2

DestDb.dbo.DestTable.Col1是(PK,nvarchar(128),非null)

DestDb.dbo.DestTable.Col2是(PK,datetimeoffset(7),非null)

dbo.SrcTable.Col1是(nvarchar(max),null)

dbo.SrcTable.Col2是(datetime2(7),not null)

我收到此错误:

  

Msg 2627,Level 14,State 1,Line 1
  违反PRIMARY KEY约束' PK_DestTable'。无法在对象' dbo.DestTable'中插入重复键。重复键值为(AAAA,2011-10-13 00:00:00.0000000 +00:00)。

我使用datediff因为目标表只需要记录源列中的日期部分(不需要时间值)。

我真的很难过,因为使用以下内容直接插入目标表格可以正常工作:

INSERT INTO [dbo].[DestTable] ([Col1], [Col2])
VALUES ('AAAA', GETDATE())
GO

2 个答案:

答案 0 :(得分:2)

您需要首先消除重复项,例如此处使用GROUP BY:

with
source as (
    SELECT [Col1], DATEADD(dd, DATEDIFF(dd, 0, [Col2]), 0)  as Col2
    FROM dbo.SrcTable as Table1
),
data as (
    select Col1,Col2 from source group by Col1,Col2 
)
INSERT INTO DestDb.dbo.DestTable ([Col1], [Col2])   
SELECT Col1,Col2 FROM data
;

您可以在第二个CTE中使用SELECT DISTINCT而不是GROUP BY,但SELECT DISTINCT的使用被许多人视为反模式。

答案 1 :(得分:0)

我希望这应该有效,因为你不需要时间部分然后转换将删除它,分组将选择col1和col2的唯一组合。另外,您已经写过DestTable的col1和col2是PK,意味着DestTable上有一个复合主键(col1,col2):

insert into DestTable
select col1, cast(Convert(varchar,Col2,101) as datetimeoffset(7)) Col2
from   SrcTable 
group  by col1, Convert(varchar,Col2,101)