SQL Server Insert if not exists
instead of below Code
BEGIN INSERT INTO EmailsRecebidos (De, Assunto, Data) VALUES (@_DE, @_ASSUNTO, @_DATA) WHERE NOT EXISTS ( SELECT * FROM EmailsRecebidos WHERE De = @_DE AND Assunto = @_ASSUNTO AND Data = @_DATA);END
replace with
BEGIN IF NOT EXISTS (SELECT * FROM EmailsRecebidos WHERE De = @_DE AND Assunto = @_ASSUNTO AND Data = @_DATA) BEGIN INSERT INTO EmailsRecebidos (De, Assunto, Data) VALUES (@_DE, @_ASSUNTO, @_DATA) ENDEND
Updated : (thanks to @Marc Durdin for pointing)
Note that under high load, this will still sometimes fail, because a second connection can pass the IF NOT EXISTS test before the first connection executes the INSERT, i.e. a race condition. See stackoverflow.com/a/3791506/1836776 for a good answer on why even wrapping in a transaction doesn't solve this.
For those looking for the fastest way, I recently came across these benchmarks where apparently using "INSERT SELECT... EXCEPT SELECT..." turned out to be the fastest for 50 million records or more.
Here's some sample code from the article (the 3rd block of code was the fastest):
INSERT INTO #table1 (Id, guidd, TimeAdded, ExtraData)SELECT Id, guidd, TimeAdded, ExtraDataFROM #table2WHERE NOT EXISTS (Select Id, guidd From #table1 WHERE #table1.id = #table2.id)-----------------------------------MERGE #table1 as [Target]USING (select Id, guidd, TimeAdded, ExtraData from #table2) as [Source](id, guidd, TimeAdded, ExtraData) on [Target].id =[Source].idWHEN NOT MATCHED THEN INSERT (id, guidd, TimeAdded, ExtraData) VALUES ([Source].id, [Source].guidd, [Source].TimeAdded, [Source].ExtraData);------------------------------INSERT INTO #table1 (id, guidd, TimeAdded, ExtraData)SELECT id, guidd, TimeAdded, ExtraData from #table2EXCEPTSELECT id, guidd, TimeAdded, ExtraData from #table1------------------------------INSERT INTO #table1 (id, guidd, TimeAdded, ExtraData)SELECT #table2.id, #table2.guidd, #table2.TimeAdded, #table2.ExtraDataFROM #table2LEFT JOIN #table1 on #table1.id = #table2.idWHERE #table1.id is null
I would use a merge:
create PROCEDURE [dbo].[EmailsRecebidosInsert] (@_DE nvarchar(50), @_ASSUNTO nvarchar(50), @_DATA nvarchar(30) )ASBEGIN with data as (select @_DE as de, @_ASSUNTO as assunto, @_DATA as data) merge EmailsRecebidos t using data s on s.de = t.de and s.assunte = t.assunto and s.data = t.data when not matched by target then insert (de, assunto, data) values (s.de, s.assunto, s.data);END