Solutions for INSERT OR UPDATE on SQL Server

后端 未结 22 2010
别跟我提以往
别跟我提以往 2020-11-21 22:23

Assume a table structure of MyTable(KEY, datafield1, datafield2...).

Often I want to either update an existing record, or insert a new record if it does

22条回答
  •  花落未央
    2020-11-21 22:50

    Many people will suggest you use MERGE, but I caution you against it. By default, it doesn't protect you from concurrency and race conditions any more than multiple statements, and it introduces other dangers:

    • Use Caution with SQL Server's MERGE Statement

    Even with this "simpler" syntax available, I still prefer this approach (error handling omitted for brevity):

    BEGIN TRANSACTION;
    
    UPDATE dbo.table WITH (UPDLOCK, SERIALIZABLE) 
      SET ... WHERE PK = @PK;
    
    IF @@ROWCOUNT = 0
    BEGIN
      INSERT dbo.table(PK, ...) SELECT @PK, ...;
    END
    
    COMMIT TRANSACTION;
    
    • Please stop using this UPSERT anti-pattern

    A lot of folks will suggest this way:

    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;
    

    But all this accomplishes is ensuring you may need to read the table twice to locate the row(s) to be updated. In the first sample, you will only ever need to locate the row(s) once. (In both cases, if no rows are found from the initial read, an insert occurs.)

    Others will suggest this way:

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

    However, this is problematic if for no other reason than letting SQL Server catch exceptions that you could have prevented in the first place is much more expensive, except in the rare scenario where almost every insert fails. I prove as much here:

    • Checking for potential constraint violations before entering TRY/CATCH
    • Performance impact of different error handling techniques

提交回复
热议问题