UPDATE(如果存在)否则在SQL Server 2008中插入



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

此示例显示了在Oracle Here中实现此目标的方法但它使用了CCD_ 3表,而CCD_。

那么,是否有SQL Server替代方案(无存储过程)

很多人会建议你使用MERGE,但我提醒你不要使用它。默认情况下,它不会像多个语句那样保护你免受并发和竞争条件的影响,但它确实会引入其他危险:

  • 对SQL Server的MERGE语句使用"小心">
  • 如果你想使用MERGE,应该避免什么
  • SQL Server UPSERT模式和反模式

即使有了这个";"更简单";语法可用,我仍然更喜欢这种方法(为了简洁起见,省略了错误处理):

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;

关于UPSERT方法的更多信息,请点击此处:

  • 请停止使用此UPSERT反模式

很多人会这样建议:

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;

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

其他人会这样建议:

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

然而,如果没有其他原因,除了让SQL Server捕获您本来可以阻止的异常要昂贵得多之外,这是有问题的,除非在几乎每个插入都失败的罕见情况下。我在这里证明了这一点:

  • 在输入TRY/CATCH之前检查潜在的约束冲突
  • 不同错误处理技术对性能的影响

不确定你认为自己通过一句话得到了什么;我认为你没有任何收获。MERGE是一个单独的语句,但无论如何,它仍然必须执行多个操作——即使它让你认为它不是。

相关内容

最新更新