更新如果存在其他INSERT在SQL Server 2008中

我想知道如何使用UPSERT或换句话说UPDATE if records exists Else enter new record使用一个语句在SQL Server中UPDATE if records exists Else enter new record操作?

这个例子展示了在Oracle 这里实现这个的方法但是它使用了SQL Server中不存在的它的Dual表。

那么,请select任何SQL Server替代scheme(无存储过程)

许多人会build议你使用MERGE ,但我警告你不MERGE 。 默认情况下,它不会保护您不受并发和竞争条件的影响,而是会引入其他危险:

http://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/

即使使用这个“更简单”的语法,我仍然更喜欢这种方法(为简洁起见省略了error handling):

 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN TRANSACTION; UPDATE dbo.table SET ... WHERE PK = @PK; IF @@ROWCOUNT = 0 BEGIN INSERT dbo.table(PK, ...) SELECT @PK, ...; END COMMIT TRANSACTION; 

很多人会这样build议:

 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN TRANSACTION; IF EXISTS (SELECT 1 FROM dbo.table WHERE PK = @PK) BEGIN UPDATE ... END ELSE BEGIN INSERT ... END COMMIT TRANSACTION; 

但是,所有这一切都是为了确保您可能需要读取表格两次以find要更新的行。 在第一个示例中,您只需要定位行(s)一次。 (在这两种情况下,如果从初始读取中没有find行,则会发生插入。)

其他人会这样build议:

 BEGIN TRY INSERT ... END TRY BEGIN CATCH IF ERROR_NUMBER() = 2627 UPDATE ... END CATCH 

但是,如果没有其他原因,让SQL Server捕获exception,那么首先要防止的exception要昂贵得多,除非几乎每个插入失败的罕见情况中,否则这是有问题的。 我在这里certificate:

不确定你认为你通过一个单一的陈述获得了什么; 我不认为你有什么收获。 MERGE是一个单一的陈述,但它仍然必须真正执行多个操作 – 尽pipe它使你认为它不。