2011-04-20 34 views
8

Tôi có một số bản ghi trong bảng có cột Trạng thái và tôi muốn chọn một bản ghi duy nhất trong đó Trạng thái = Đang chờ xử lý và trong cùng một dấu truy vấn nguyên tử nó như Status = InProcess. Cách tốt nhất để làm điều đó là gì?Cách chọn bản ghi từ cơ sở dữ liệu và cập nhật nó trong truy vấn nguyên tử

Điều này là cần thiết vì nhiều truy vấn có thể chạy đồng thời cố gắng xử lý các bản ghi này và tôi không muốn hai luồng được chọn cùng một bản ghi để xử lý.

Trả lời

13

Bạn có thể sử dụng khoản OUTPUT:

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

Ở đây bạn có thể sử dụng chèn tên bảng nếu bạn muốn nhận được hàng với trạng thái mới hoặc xóa khi cũ.

+1

+1. Đã học một điều gì đó mới hôm nay :). Điều này sẽ trả lại hồ sơ ngay trước khi cập nhật nó – tobias86

+0

Cảm ơn rất nhiều. điều này thật tuyệt. Chính xác những gì tôi đang tìm kiếm. BTW nếu có ai quan tâm đến công việc này trong SQL2005 trở lên. – lahsrah

+1

Điều này không chỉ làm một bản ghi mặc dù được chỉ định trong câu hỏi. –

3

này nên làm các trick

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

SQL 2008 nên chăm sóc của bất kỳ khóa cho bạn.

+0

Tôi cũng cần phải lựa chọn kỷ lục đó. – lahsrah

+0

Vì vậy, những gì cần phải xảy ra đầu tiên? Bạn có muốn chọn nó trước và sau đó cập nhật hoặc ngược lại không? – tobias86

5

Đây là một bài viết về Using tables as Queues.

Với bảng này create table T (ID int identity, Status varchar(15)) Một cái gì đó như thế này sẽ giữ cho bạn an toàn khỏi các bế tắc.

;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 Tôi sẽ sử dụng 'with (rowlock, updlock, readpast)' mặc dù. –

0

này Sau đây là loại một hack, nhưng nó làm việc cho tôi cho nguyên tử đọc/cập nhật:

declare temp1, temp2, ...; 
update table 
    set temp1=column1, 
     temp2=column2, ... 
     column1=expression1, 
     column2=expression2, ... 
where conditions; 
select temp1, temp2, ...; 
Các vấn đề liên quan