插入和更新的单独存储过程?

Roy*_*mir 5 sql-server-2008 sql-server stored-procedures physical-design upsert

我在 Microsoft SQL Server 中有一个表。有时需要更新,有时需要插入。我可以写2个存储过程:

InsertNewPerson
UpdatePertsonById
Run Code Online (Sandbox Code Playgroud)

但我正在考虑编写 1 个存储过程而不是 ( SetPerson),这两个过程都可以(如果有ID,则是update操作,否则insert)。

我应该创建一个存储过程(只需要维护一个)还是应该创建两个不同的存储过程?

Mar*_*ith 9

据我了解,您实际上并不是在谈论UPSERT将两个不同的 CRUD 操作合并到一个存储过程中。

CREATE PROC InsertOrUpdateYourTable @Id int = NULL OUTPUT,
                                    @Foo INT,
                                    @Bar VARCHAR(10)
AS
    IF @Id IS NULL
      BEGIN
          INSERT INTO YourTable
                      (Foo,
                       Bar)
          VALUES      (@Foo,
                       @Bar)

          SET @Id = SCOPE_IDENTITY()
      END
    ELSE
      BEGIN
          UPDATE YourTable
          SET    Foo = @Foo,
                 Bar = @Bar
          WHERE  Id = @Id
      END 
Run Code Online (Sandbox Code Playgroud)

我看到的好处是,如果表结构发生变化,您不必维护两个单独的参数列表。缺点是单个存储过程现在有两个职责并且不太容易理解。

我通常会选择将它们分成两个存储过程。

RE:“你能详细说明一个 upsert 的样子吗”

CREATE PROC UpsertYourTable
@Id int,
@Foo int,
@Bar varchar(10)
AS
MERGE YourTable WITH (HOLDLOCK)  AS T
        USING ( VALUES ( @Id, @Foo, @Bar ) ) 
              AS source ( Id, Foo, Bar)
        ON ( T.Id = source.Id )
        WHEN MATCHED 
            THEN 
        UPDATE SET
                Foo = source.Foo ,
                Bar = source.Bar
        WHEN NOT MATCHED 
            THEN    
        INSERT  (Id, Foo , Bar)
               VALUES 
               (@Id, @Foo , @Bar);
Run Code Online (Sandbox Code Playgroud)

这假设Id不再是一IDENTITY列。使用的原因HOLDLOCK 在这里解释