【问题标题】:how can I Update top 100 records in sql server如何更新 sql server 中的前 100 条记录
【发布时间】:2010-11-14 23:07:44
【问题描述】:

我想更新 SQL Server 中的前 100 条记录。我有一个表T1 字段F1F2T1 有 200 条记录。我想更新前 100 条记录中的 F1 字段。如何在 SQL Server 中根据TOP 100 进行更新?

【问题讨论】:

    标签: sql sql-server tsql sql-update


    【解决方案1】:

    注意,UPDATE 语句需要括号:

    update top (100) table1 set field1 = 1
    

    【讨论】:

    • 知道如何使用order by吗?
    • @JoePhilllips 使用 Martin Smith 的答案进行排序
    • 然而,这些不是前 100 条记录,而只是 100 条任意选择的记录。前 100 名将包括一些对记录进行排名的顺序。
    • 这回答了“按要求”的问题,但没有一些 ORDER 的 TOP 是没有意义的(并且不可预测的)。请参阅 Martin Smith 的答案。
    • 如果您尝试分块更新大表,这并非没有意义,但这需要 WHERE 子句(例如 WHERE field1 IS NULL)。所以是的,如果没有 either ORDER BY 或 WHERE 子句,TOP 是没有意义的——在这两种情况下,大型表都需要索引才能提高效率。
    【解决方案2】:

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

    尽管如此,SQL Server 允许,但 doesn't guarantee a deterministic result

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

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

    【讨论】:

    • 你说的毫无意义,但那不是真的。我承认,/通常/,当您使用TOP 时,您应该将它与ORDER BY 一起使用,因为您感兴趣的是某事的“最多”或“最少”。但是,在其他情况下,您可能只对获取一条匹配记录感兴趣。像我今天一样!我需要一次解决一个数据问题(周期)。整个修复过程涉及一个 db 脚本、一些用户干预和一些应用程序操作。我们不在乎首先处理哪个记录。我们只是关心我们一次处理一个。
    • @MetaFight 但是你会有一个WHERE 子句来排除以前处理的记录。书面和公认答案的问题非常没有意义。顺便说一句:用于将表用作队列this is quite a useful link
    • 我需要使用没有 order by 的 top 以便我可以运行异步进程。 where 子句不会包括那些已经处理过的,但我一次只能处理这么多。所以它有一个完全有效的用例。
    • @Martin Smith:假设您要批量更新,例如一次 10000 个。似乎对此很有用,顺序无关紧要。这怎么“没有意义”?
    • @notfed 这与上面 cmets 中已经讨论到死的情况相同。在这种情况下,您的查询会 not 看起来像接受的答案中的那个吗?您需要一个where 子句来避免一次又一次地处理相同的行。
    【解决方案3】:
    update tb set  f1=1 where id in (select top 100 id from tb where f1=0)
    

    【讨论】:

    • 为确定性顺序添加 ORDER BY 会更好,即update tb set f1=1 where id in (select top 100 id from tb where f1=0 order by id asc)
    • 拥有数百万张桌子,这非常慢
    【解决方案4】:

    对于像我这样仍然坚持使用 SQL Server 2000 的人,SET ROWCOUNT {number}; 可以在 UPDATE 查询之前使用

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

    将更新限制为 100 行

    至少自 SQL 2005 以来它已被弃用,但自 SQL 2017 起它仍然有效。 https://docs.microsoft.com/en-us/sql/t-sql/statements/set-rowcount-transact-sql?view=sql-server-2017

    【讨论】:

    • SET ROWCOUNT 影响触发器以及正在更新的命令。如果您设置了级联删除,如果子表中存在的子行数超过行数,则事务可能会失败。
    • 话虽如此,SET ROWCOUNT @RowCountParameter;是有效的语法,而 SELECT TOP @RowCountParamter * FROM TableName 是无效的。如果您需要配置要更新的行,SET ROWCOUNT # 目前是更好的选择,前提是您没有启用级联删除的子表。
    • 在 SQL Server 2017 中,现在可以在 TOP 子句中使用 @variable:docs.microsoft.com/en-us/sql/t-sql/queries/…
    【解决方案5】:

    更酷的是,您可以使用内联表值函数来选择要更新的行(以及通过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 语句的语法的真正力量存在。

    【讨论】:

      【解决方案6】:

      您还可以使用别名和加入从选择中更新:

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

      【讨论】:

        【解决方案7】:

        试试:

        UPDATE Dispatch_Post
        SET isSync = 1
        WHERE ChallanNo 
        IN (SELECT TOP 1000 ChallanNo FROM dbo.Dispatch_Post ORDER BY 
        CreatedDate DESC)
        

        【讨论】:

        【解决方案8】:

        这段代码可以完成它的工作

        UPDATE TOP (100) table_name set column_name = value;
        

        如果你想显示最后 100 条记录,你可以根据需要使用它。

        With OrnekWith
        as
        (
        Select Top(100) * from table_name Order By ID desc
        )
        Update table_name Set column_name = value;
        

        【讨论】:

          【解决方案9】:

          TOP 限定符也可以用来限制手动错误更新的行数。

          考虑以下 UPDATE 语法。

          UPDATE TOP (1) table1 SET column1 = 0 WHERE column_pk = '123'
          

          如果没有 TOP 子句,如果您正在执行手动更新并且您的鼠标文本选择仅从“UPDATE”到“WHERE”子句之前进行选择,则更新将应用于所有行。使用 TOP 子句,只有一行会得到不需要的更新。

          TOP 约束可以限制缺少或不正确的 WHERE 子句或 ORDER BY 子句的损害。当知道应该只更新一行或几行时,这会很有帮助。

          【讨论】:

            猜你喜欢
            • 2021-05-22
            • 2012-09-29
            • 2013-12-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多