如何更新sql server中的前100条记录

Raj*_*sh 376 sql t-sql sql-server sql-update

我想更新SQL Server中的前100条记录.我有一个表T1包含字段F1F2.T1有200条记录.我想更新F1前100条记录中的字段.如何TOP 100在SQL Server中进行更新?

Uma*_*med 650

注意,UPDATE语句需要括号:

update top (100) table1 set field1 = 1
Run Code Online (Sandbox Code Playgroud)

  • 任何想法如何使用`order by`? (26认同)
  • @JoePhilllips使用Martin Smith的答案来订购 (7认同)
  • 如果您尝试分块更新大型表,这并非毫无意义,但这需要 WHERE 子句(例如 WHERE field1 IS NULL)。所以,是的,如果没有 ORDER BY 或 WHERE 子句,TOP 就没有意义 - 并且对于这两种情况,大表都需要索引才能高效。 (7认同)
  • 然而,这些不是前 100 条记录,而是任意选择的 100 条记录。前 100 名将包括对记录进行排名的一些顺序。 (2认同)
  • 这回答了“按要求”的问题,但 TOP 没有一些 ORDER 就毫无意义(且不可预测)。请参阅 Martin Smith 的答案。 (2认同)

Mar*_*ith 291

没有一个ORDER BY完整的想法TOP没有多大意义.你需要有一个一致的定义,哪个方向是"向上",哪个是"向下",因为top的概念是有意义的.

尽管如此,SQL Server允许它但不保证确定性结果.

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

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

  • 你说没有意义,但事实并非如此.我承认,/通常/,当你使用`TOP`赔率时,你应该将它与`ORDER BY'一起使用,因为你感兴趣的东西就像是"最"或"最少"的东西.但是,在其他情况下,您可能只对获得一个匹配记录感兴趣.今天就像我一样!我需要一次修复一个数据问题(周期).整个修复过程涉及db脚本,一些用户干预和一些应用程序操作.我们并不关心首先处理WHICH记录.我们只关心我们一次处理一个. (70认同)
  • @MetaFight但是你会有一个`WHERE`子句来排除以前处理过的记录.书面和接受的答案这个问题毫无意义.顺便说一句:将表用作队列[这是一个非常有用的链接](http://rusanu.com/2010/03/26/using-tables-as-queues/) (17认同)
  • 我需要在没有顺序的情况下使用top,以便我可以运行异步进程.where子句不包括那些已经处理过的子句,但我一次只能处理这么多子句.所以它有一个完全有效的用例. (10认同)
  • @notfed这与上述评论中已经讨论过的死亡情况相同.在这种情况下你的查询*不会*看起来像是接受的答案中的那个吗?你需要一个`where`子句来避免一次又一次地处理相同的行. (5认同)
  • @Martin Smith:假设你想分批更新,一次说10000.似乎很好用于此,顺序无关紧要.这怎么"没有意义"? (4认同)
  • 对我来说听起来很有意义:我有一个相同资源的列表,我想抓住一个.update top(1)允许我将一个标记为对我使用.我可以很容易地为我的使用分配10等,然后稍后查询以查看我已经分配了哪些. (3认同)
  • @Legolas - 您只是重复上面讨论过的使用表作为堆队列的用例.如何停止检索已被另一个进程标记为正在使用的行?大概你必须有一个where子句. (3认同)
  • 我发现UPDATE TOP没有where或order by子句对于填充数据库字段进行测试很有用。特别是在将新的数据库列添加到现有数据库之后。 (2认同)
  • @Martin Smith:我同意你需要一个where子句.我指的是你的引用,"没有ORDER BY整个TOP的想法没有多大意义" (2认同)
  • @MartinSmith您只有三个人试图告诉您同一件事,但无论如何。 (2认同)
  • @Martin Smith 正确阅读评论。在我的示例中,我不关心顶部的内容,我只想将更新限制为 100 行,仅此而已。我不在乎_到底_正在更新。因此,即使您所说的“方向”未定义,顶部也是_非常_有意义的。但我现在注意到其他几个人已经提供了类似(几乎相同,甚至)的用例,而您只是拒绝接受它们,所以我毫不怀疑您会找到某种方法来告诉我我错了。我想,无论你的船漂浮在什么地方。 (2认同)
  • @斯图尔特。不可以。CTE 要求前面的语句以分号结束。Sql Server 通常不需要这个,所以这只是为了抢先人们把它放在非分号分隔的代码之后并看到错误消息。 (2认同)

Cla*_*o B 14

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

SET ROWCOUNT 100;
UPDATE Table SET ..;
SET ROWCOUNT 0;
Run Code Online (Sandbox Code Playgroud)

将更新限制为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 影响触发器以及正在更新的命令。如果您有级联删除集,如果子表中存在的子行数超过行数,则事务可能会失败。 (2认同)

小智 12

update tb set  f1=1 where id in (select top 100 id from tb where f1=0)
Run Code Online (Sandbox Code Playgroud)

  • 对于数百万张表来说,这是非常慢的 (2认同)