Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Select a record from the database and update it in an atomic query

I have a number of records in a table with a Status column and I want to select a single record where Status = Pending and in the same atomic query mark it as Status = InProcess. What's the best way to do that?

This is needed because multiple queries can be running at the same time trying to process these records and I don't want two threads to be picking up the same record to process.

like image 987
lahsrah Avatar asked Apr 20 '11 06:04

lahsrah


People also ask

How do you update a specific record in SQL?

The UPDATE command in SQL is used to modify or change the existing records in a table. If we want to update a particular value, we use the WHERE clause along with the UPDATE clause. If you do not use the WHERE clause, all the rows will be affected.

Can we do an update from a select statement?

The UPDATE from SELECT query structure is the main technique for performing these updates. An UPDATE query is used to change an existing row or rows in the database. UPDATE queries can change all tables' rows, or we can limit the update statement affects for certain rows with the help of the WHERE clause.


2 Answers

You can use OUTPUT clause:

UPDATE [table]
SET Status = 'InProcess'
OUTPUT deleted.*
WHERE Status = 'Pending'

Here you can use inserted table name if you want to get row with new status or deleted when old.

like image 196
Dalex Avatar answered Sep 23 '22 05:09

Dalex


Here is an article about Using tables as Queues.

With this table create table T (ID int identity, Status varchar(15)) Something like this should keep you safe from deadlocks.

;with cte as
(
  select top 1 *
  from T with (rowlock, readpast)
  where Status = 'Pending'
  order by ID
)
update cte
set Status = 'InProcess'
output inserted.ID, inserted.Status
like image 26
Mikael Eriksson Avatar answered Sep 20 '22 05:09

Mikael Eriksson