2009-12-02 81 views
2

我有一個SQL查詢是這樣的:SQL Server在同一語句中選擇並更新?

SELECT TOP (@TopType) AdvertID, IsAdvertImage, AdvertData 
FROM Adverts 
WHERE AdvertSize = @AdvertSize 
ORDER BY NEWID() 

表中的每一行的廣告也有一個稱爲視圖的列,是有可能還會增加1意見對已獲取的條幅?所以我將TopType設置爲4並獲得4個橫幅,這些橫幅的視圖增加了1,這樣我就可以跟蹤橫幅顯示的次數。

回答

5
WITH cte AS (
SELECT TOP (@TopType) 
AdvertID, IsAdvertImage, AdvertData, Views 
FROM Adverts 
WHERE AdvertSize = @AdvertSize 
ORDER BY NEWID()) 
UPDATE cte 
SET Views = Views + 1 
OUTPUT INSERTED.AdvertID 
, INSERTED.IsAdvertImage 
, INSERTED.AdvertData; 

但ORDER BY NEWID()會表現糟糕。即使使用TOP(1)仍然需要掃描整個表,將tempdb中的選定列後臺處理,然後從中取出TOP。並且還將成爲視圖=視圖+ 1個X鎖和全掃描S鎖之間的更新衝突富礦...

+0

我被卡住了,什麼是解決此問題的最佳解決方案?無需擔心S鎖。這個Select語句在一個存儲過程中,所以我可以修改它。重要的部分是它將x個隨機廣告發回給調用者。 – Patrick 2009-12-02 22:24:12

+0

我不明白。如果你不能修改存儲過程,爲什麼你要求在同一個語句中選擇*和* update *? – 2009-12-02 22:27:49

+0

爲什麼更新必須在同一個語句中發生?幾年前我建立了一個廣告服務器,並且統計數據的記錄相當快,但是這絕不應該中斷「拉」橫幅。我們不是通過表格中的選擇來記錄「視圖」,而是通過命中登錄頁面,將其記錄到稍後消耗的日誌文件中。它可以離線處理,因爲視圖1的增加不必同時發生......特別是因爲您只是隨便抽出任意橫幅,爲什麼它必須立即更新? – 2009-12-02 23:25:50