理想情况下,我想做到这一点:
UPDATE TOP (10) messages SET status=10 WHERE status=0 ORDER BY priority DESC;
我想从数据库中获取前10条状态为0的可用消息并将它们锁定(状态为10)。优先级较高的消息应首先获取。
不幸的是,MS SQL不允许在update语句中使用order by子句。
那么有什么方法可以绕过这个限制呢?
理想情况下,我想做到这一点:
UPDATE TOP (10) messages SET status=10 WHERE status=0 ORDER BY priority DESC;
我想从数据库中获取前10条状态为0的可用消息并将它们锁定(状态为10)。优先级较高的消息应首先获取。
不幸的是,MS SQL不允许在update语句中使用order by子句。
那么有什么方法可以绕过这个限制呢?
;WITH q AS
(
SELECT TOP 10 *
FROM messages
WHERE status = 0
ORDER BY
priority DESC
)
UPDATE q
SET status = 10
您可以执行一个子查询,首先获取按优先级排序的前10个ID,然后更新位于该子查询中的记录:
UPDATE messages
SET status=10
WHERE ID in (SELECT TOP (10) Id
FROM Table
WHERE status=0
ORDER BY priority DESC);
我可以提供一个更好的方法 - 您并不总是拥有标识字段的豪华条件:
UPDATE m
SET [status]=10
FROM (
Select TOP (10) *
FROM messages
WHERE [status]=0
ORDER BY [priority] DESC
) m
UPDATE messages SET
status=10
WHERE ID in (SELECT TOP (10) Id FROM Table WHERE status=0 ORDER BY priority DESC);
如下评论所述,您也可以使用SET ROWCOUNT子句,但仅适用于SQL Server 2014及更早版本。
SET ROWCOUNT 10
UPDATE messages
SET status = 10
WHERE status = 0
SET ROWCOUNT 0
DECLARE @t TABLE (id INT)
INSERT @t (id)
SELECT TOP 10 id
FROM messages
WHERE status = 0
ORDER BY priority DESC
UPDATE messages
SET status = 10
WHERE id IN (SELECT id FROM @t)
rowcount
在需要任意10行的情况下很有效,但您无法指定 order by
来确定确切的10行。 您使用临时表的示例可以工作,但它依赖于一个id列。 - Ed Avis
WITH
语句时,一定要在前面加上分号;
,否则会出现这个错误。希望能对大家有所帮助。 - Shaiju T