2013-11-20 48 views
0

使用MS-SQL,我有一個INSERT ... SELECT語句,該語句填充具有唯一密鑰IGNORE_DUP_KEY = ON的表。INSERT SELECT和IGNORE_DUP_KEY,如何檢索丟棄的行?

有沒有容易方式我可以得到被丟棄的行,因爲它們是重複的? (最好在聲明完成後)

+1

你用什麼sql? mysql? SQL Server 2012? –

+0

@LorenzMeyer:它需要與MS-SQL 2005,2008和2012兼容 – jplanglais

+0

@MartinSmith:我使用IGNORE_DUP_KEY = OFF以防止INSERT SELECT失敗。 – jplanglais

回答

1

OUTPUT clause是這裏的關鍵。

create table dbo.IDKsource ( 
    SNumber int not null, 
    SText varchar(100) not null 
) ; 
go 
insert into dbo.IDKsource 
values (1, 'aaaaa'), (2, 'bbbbb'), (1, 'cccccc'), (3, 'dddddd') ; 
go 

create table dbo.IDKOntarget ( 
    SNumber int not null unique with (ignore_dup_key = on), 
    SText varchar(100) not null 
) ; 
go 

-- The following lines must all be in one batch! 
declare @RecordsWereInserted table (
    SNumber int not null , 
    SText varchar(100) not null 
) ; 

insert into dbo.IDKOntarget (SNumber , SText) 
output inserted.* into @RecordsWereInserted 
select SNumber , SText 
from dbo.IDKSource ; 

select SNumber , SText 
from dbo.IDKsource 
except 
select SNumber , SText 
from @RecordsWereInserted ; 

如果你想保持插入的數據的時間超過一個批次(或您的SQL Server版本不支持表變量),然後把我的表變量RecordsWereInserted與實際的表。

注意:我的第一種方法是直接使用INSERT語句與EXCEPT,但SQL Server不允許帶有EXCEPT,INTERSECT或UNION的DML語句。

+0

+1這很有趣我沒有意識到'output inserted'還會包含因'IGNORE_DUP_KEY'而未實際插入的行 –

+0

它不會,Martin,這就是爲什麼我們必須使用EXCEPT查詢。 –

+0

啊我看到我沒有正確地看着它。我以爲你正在輸出結果並對基表執行「EXCEPT」。 –