2011-04-20 16 views
8

ステータスカラムのあるテーブルに複数のレコードがあり、ステータス=ペンディングで、同じアトミッククエリマークそれはStatus = InProcessである。それを行う最善の方法は何ですか?データベースからレコードを選択してアトミッククエリで更新する方法

これは、複数のクエリを同時に実行してこれらのレコードを処理しようとしているため、2つのスレッドが同じレコードを処理して処理しないようにするために必要です。

答えて

13

あなたはOUTPUT句を使用することができますときに、古い新しい状況やを持つ行を取得したい場合は、挿入テーブル名を使用することができます。ここ

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

を削除しました。

+1

+1。新しい何かを今日学んだ:)。これは更新する直前にレコードを返します – tobias86

+0

ありがとうございます。これは素晴らしいです。まさに私が探していたもの。興味のある方は、SQL2005以降で動作します。 – lahsrah

+1

これは質問に指定されているように単一のレコードを行うだけではありません。 –

3

これは

UPDATE [table] 
SET Status = 'InProcess' 
WHERE Status = 'Pending' 

SQL 2008はあなたのための任意のロックの世話をする必要がありますトリックを行う必要があります。

+0

私もそのレコードを選択する必要があります。 – lahsrah

+0

だからまず何が起こる必要がありますか?最初に選択してから更新したいのですか? – tobias86

5

ここには約Using tables as Queuesの記事があります。

このテーブルの場合create table T (ID int identity, Status varchar(15)) デッドロックが発生しないようにする必要があります。

;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 
+1

+1 'with(rowlock、updlock、readpast)を使用します。 –

0

この次は、ハッキングの一種であるが、それはアトミック読み取り/更新のために私の仕事:

declare temp1, temp2, ...; 
update table 
    set temp1=column1, 
     temp2=column2, ... 
     column1=expression1, 
     column2=expression2, ... 
where conditions; 
select temp1, temp2, ...; 
関連する問題