Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to implement a conditional Upsert stored procedure?
    primarykey
    data
    text
    <p>I'm trying to implement your basic UPSERT functionality, but with a twist: sometimes I don't want to actually update an existing row.</p> <p>Essentially I'm trying to synchronize some data between different repositories, and an Upsert function seemed like the way to go. So based largely on <a href="https://stackoverflow.com/questions/13540/insert-update-stored-proc-on-sql-server/193876#193876">Sam Saffron's answer to this question</a>, as well as some other research and reading, I came up with this stored procedure:</p> <p>(note: I'm using MS SQL Server 2005, so the MERGE statement isn't an option)</p> <pre><code>CREATE PROCEDURE [dbo].[usp_UpsertItem] -- Add the parameters for the stored procedure here @pContentID varchar(30) = null, @pTitle varchar(255) = null, @pTeaser varchar(255) = null AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; BEGIN TRANSACTION UPDATE dbo.Item WITH (SERIALIZABLE) SET Title = @pTitle, Teaser = @pTeaser WHERE ContentID = @pContentID IF @@rowcount = 0 INSERT INTO dbo.Item (ContentID, Title, Teaser) VALUES (@pContentID, @pTitle, @pTeaser) COMMIT TRANSACTION END </code></pre> <p>I'm comfortable with this for a basic Upsert, but I'd like to make the actual update conditional on the value of another column. Think of it as "locking" a row so that no further updates may be made by the Upsert procedure. I could change the UPDATE statement like so:</p> <pre><code>UPDATE dbo.Item WITH (SERIALIZABLE) SET Title = @pTitle, Teaser = @pTeaser WHERE ContentID = @pContentID AND RowLocked = false </code></pre> <p>But then the subsequent Insert would fail with a unique constraint violation (for the ContentID field) when it tries to insert a row that already exists but wasn't updated because it was "locked".</p> <p>So does this mean that I no longer have a classic Upsert, i.e. that I'll have to select the row every time to determine whether it can be updated or inserted? I'm betting that's the case, so I guess what I'm really asking for is help getting the transaction isolation level correct so that the procedure will execute safely.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload