更新如果存在其他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:
- http://www.mssqltips.com/sqlservertip/2632/checking-for-potential-constraint-violations-before-entering-sql-server-try-and-catch-logic/
- http://www.sqlperformance.com/2012/08/t-sql-queries/error-handling
不确定你认为你通过一个单一的陈述获得了什么; 我不认为你有什么收获。 MERGE
是一个单一的陈述,但它仍然必须真正执行多个操作 – 尽pipe它使你认为它不。