2014-02-27 75 views
0

我有一個表命名Car如何選擇和更新單個SQL查詢中的選定行?

Table car (id int NOT NULL, plate int NOT NULL, sent_to_server bit NOT NULL); 

我要選擇未發送到服務器的所有汽車尚未

SELECT * 
FROM car 
WHERE sent_to_server = 0; 

然後,我應該更新我的DB

UPDATE car 
SET sent_to_server = 1 
WHERE sent_to_server = 0; 

我有多線程,所以這不會工作(多線程正在讀取和寫入數據庫在同一時間 - (即時通訊使用SQL服務器))

如何在一個查詢中執行2個查詢? 還是有更好的解決方案!?

注:我使用C#與petapoco庫(!如果它很重要)

+0

爲什麼你需要的是選擇什麼呢? – Ziouas

+0

我發送了哪些汽車沒有發送到服務器呢。 – amin

+0

其客戶端服務器應用程序和服務器跟蹤多個客戶端應用程序。 – amin

回答

3

只要您使用SQL Server 2005或更高版本,就可以在單個查詢中使用OUTPUT

UPDATE Car 
SET sent_to_server = 1 
OUTPUT Inserted.id, Inserted.plate 
WHERE sent_to_server = 0; 

這將更新sent_to_server爲零的行並返回修改的行。無需交易。

SQL Fiddle

+0

'UPDATE Car SET sent_to_server = 1 OUTPUT插入。* WHERE sent_to_server = 0;'也可以。很棒!,謝謝。 – amin

+1

@ user1575632 - 是的,'*'也可以工作,但不需要返回表字段,你已經知道'sent_to_server'的結果是什麼;)只返回你需要的信息使查詢儘可能快。 – Tony

2

我認爲你需要使用事務。 請將您的疑問都在下面的代碼

 
BEGIN TRANSACTION 
select * from car where sent_to_server = 0; 
update car set sent_to_server = 1 where sent_to_server = 0; 
COMMIT TRANSACTION 

默認情況下將含有交易鎖定表來讀取其他連接,因此其他線程將無法讀取結果,直到本次交易不COMMITED。

+0

我認爲這解決了我的問題。謝謝 – amin

+0

它沒有與我的庫(C#中的petapoco)一起工作。但它有幫助。 petapoco支持交易。 – amin

1

另一個想法@託尼的回答,這是對sent_to_server列類型更改爲GUID,並把那裏的處理批號。

例(僞):

var batch = new Guid(); 
update car set sent_to_server = @batch where sent_to_server is null;  
select * from car where sent_to_server = @batch;