2009-12-02 80 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