我想更新SQL Server的前100条记录。我有一个包含字段F1和F2的表T1。T1有200条记录。我想更新排名前100的F1赛场。如何根据SQL Server的TOP 100进行更新?


当前回答

更酷的是,您可以使用内联表值函数来选择要更新哪些行(以及通过TOP更新多少行)。那就是:

UPDATE MyTable
SET Column1=@Value1
FROM tvfSelectLatestRowOfMyTableMatchingCriteria(@Param1,@Param2,@Param3)

对于表值函数,你有一些有趣的选择要更新的行,如:

CREATE FUNCTION tvfSelectLatestRowOfMyTableMatchingCriteria
(
    @Param1 INT,
    @Param2 INT,
    @Param3 INT
)
RETURNS TABLE AS RETURN
(
    SELECT TOP(1) MyTable.*
    FROM MyTable
    JOIN MyOtherTable
      ON ...
    JOIN WhoKnowsWhatElse
      ON ...
    WHERE MyTable.SomeColumn=@Param1 AND ...
    ORDER BY MyTable.SomeDate DESC
)

...,在简化UPDATE语句语法的同时,仅确定性地更新顶部选定行的真正强大之处在于(在我看来)。

其他回答

对于那些像我一样仍然停留在SQL Server 2000, SET ROWCOUNT {number};可以在UPDATE查询之前使用

SET ROWCOUNT 100;
UPDATE Table SET ..;
SET ROWCOUNT 0;

是否将更新限制在100行

它至少从SQL 2005开始就被弃用了,但截至SQL 2017,它仍然可以工作。 https://learn.microsoft.com/en-us/sql/t-sql/statements/set-rowcount-transact-sql?view=sql-server-2017

你也可以使用别名和join从select中更新:

UPDATE  TOP (500) T
SET     T.SomeColumn = 'Value'
FROM    SomeTable T
        INNER JOIN OtherTable O ON O.OtherTableFK = T.SomeTablePK
WHERE   T.SomeOtherColumn = 1

如果没有ORDER BY, TOP的整个概念就没有多大意义。你需要对哪个方向是“向上”,哪个方向是“向下”有一个一致的定义,这样顶部的概念才有意义。

尽管如此,SQL Server允许这样做,但不能保证结果是确定的。

接受的答案中的UPDATE TOP语法不支持ORDER BY子句,但是可以通过使用CTE或派生表来定义所需的排序顺序来获得确定性语义,如下所示。

;WITH CTE AS 
( 
SELECT TOP 100 * 
FROM T1 
ORDER BY F2 
) 
UPDATE CTE SET F1='foo'

更酷的是,您可以使用内联表值函数来选择要更新哪些行(以及通过TOP更新多少行)。那就是:

UPDATE MyTable
SET Column1=@Value1
FROM tvfSelectLatestRowOfMyTableMatchingCriteria(@Param1,@Param2,@Param3)

对于表值函数,你有一些有趣的选择要更新的行,如:

CREATE FUNCTION tvfSelectLatestRowOfMyTableMatchingCriteria
(
    @Param1 INT,
    @Param2 INT,
    @Param3 INT
)
RETURNS TABLE AS RETURN
(
    SELECT TOP(1) MyTable.*
    FROM MyTable
    JOIN MyOtherTable
      ON ...
    JOIN WhoKnowsWhatElse
      ON ...
    WHERE MyTable.SomeColumn=@Param1 AND ...
    ORDER BY MyTable.SomeDate DESC
)

...,在简化UPDATE语句语法的同时,仅确定性地更新顶部选定行的真正强大之处在于(在我看来)。

注意,括号对于UPDATE语句是必需的:

update top (100) table1 set field1 = 1