简体   繁体   中英

SQL Server - Is it possible to return an existing column value before a row update?

I'm writing a query that updates a user's vote ( ForumVotes ) for a forum post ( ForumPosts ). Users can vote up or down (the vote will equal 1 or -1). This question is specific to changing a user's vote, so a vote record already exists in the ForumVotes table.

The ForumPosts table stores the total score for each post, so I need to keep this field in synch. To recalculate the total score I need to first subtract the old vote before adding the new vote, so I need to get the old vote before updating the user's vote record.

I know I can do this with 2 queries, but I'm wondering if it's possible (in SQL Server 2008) for an UPDATE to return the value of a column prior to performing the update?

Here's an example:

TABLE ForumPosts (
    postID bigint,
    score int,
    ... etc
)

-- existing vote is in this table:

TABLE ForumVotes (
    postFK bigint,
    userFK bigint,
    score int
)

A simple query to update a user's vote

UPDATE ForumVotes 
SET score = @newVote 
WHERE postFK = @postID
AND userFK = @userID

Can this query be modified to return the old score before the update?

Try the OUTPUT clause:

declare @previous table(newscore int, Oldscore int, postFK int, userFK int)

UPDATE ForumVotes 
SET score = @newVote 
OUTPUT inserted.score,deleted.score, deleted.postFK, deleted.userFK into @previous
WHERE postFK = @postID
AND userFK = @userID

select * from @previous

If it is a single row affected query (ie; update using key(s)) then;

declare @oldVote varchar(50)

update ForumVotes 
set score = @newVote, @oldVote = score 
where postFK = @postId and userFK = @userId

--to receive the old value
select @oldVote 

I'll expand upon @HLGEM's answer by showing you don't need an intermediate @previous table, you can rely on OUTPUT returning data directly without any variables, only aliasing:

UPDATE
    ForumVotes
SET
    Score = @newVote
OUTPUT
    INSERTED.Score AS NewScore,
    DELETED.Score  AS OldScore
WHERE
    PostFK = @postId AND
    USerFK = @userId

If you run this directly, you'll get a table returned with 1 row of data and 2 columns: NewScore and OldSCore .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM