UPDATE if exists else INSERT in SQL Server 2008
本问题已经有最佳答案,请猛点这里访问。
我想知道如何使用一个语句在SQL Server中使用
此示例显示了在Oracle Here中实现此目的的方法
但它使用
那么,任何SQL Server替代品(没有存储过程)好吗?
很多人会建议你使用
http://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/
即使使用这种"更简单"的语法,我仍然更喜欢这种方法(为简洁省略了错误处理):
1 2 3 4 5 6 7 8 | 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; |
很多人会这样建议:
1 2 3 4 5 6 7 8 9 10 11 | 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; |
但所有这一切都可以确保您可能需要两次读取表以找到要更新的行。在第一个示例中,您只需要找到一次行。 (在这两种情况下,如果从初始读取中找不到行,则会发生插入。)
其他人会建议这样:
1 2 3 4 5 6 7 | BEGIN TRY INSERT ... END TRY BEGIN CATCH IF ERROR_NUMBER() = 2627 UPDATE ... END CATCH |
但是,如果除了在几乎每个插入失败的罕见情况下,除了让SQL Server捕获您可能首先阻止的异常之外没有其他原因,这是有问题的。我在这里证明了这一点:
- 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
通过单一陈述不确定您认为您获得了什么;我认为你没有任何收获。