【发布时间】:2014-08-07 21:41:30
【问题描述】:
我需要从 SQL Server 2008 R2 的大表中删除大部分记录。此表上有一个巨大的 DELETE 触发器,用于清理其他表。我需要批量运行删除,这样我才能看到它在做什么,所以我编写了一个循环来自动化批处理,但提供状态消息。我遇到的问题是,如果我在 DELETE 语句周围使用 SET NOCOUNT,它只会在循环完成后给我消息。我只是想要一种方法来抑制 DELETE 语句“受影响的行”消息,但仍然可以实时获取我的 PRINT 消息。我无法更改 DELETE 触发器。我真的只是希望它像@ECHO OFF 一样运行
DECLARE @counter INT;
DECLARE @rowstogo INT;
SET @rowstogo = ( SELECT COUNT(1) FROM Customer WHERE Attribute1 <> 11 );
SET @counter = 1;
--while @rowstogo > 0
WHILE @counter<5 --Test of only 4 iterations
BEGIN
PRINT 'Pass '+ CAST(@counter as varchar) +': '+ CAST(@rowstogo as varchar)+' records'
SET NOCOUNT ON
DELETE TOP (100) FROM Customer WHERE Attribute1 <> 11
SET NOCOUNT OFF
SET @counter = @counter + 1
SET @rowstogo = ( select COUNT(1) from Customer where Attribute1 <> 11 )
PRINT CAST ( @rowstogo as varchar ) + ' records remaining'
PRINT '--------------------------------'
END
【问题讨论】:
-
而不是
PRINT 'foo';使用RAISERROR('foo',0,1) WITH NOWAIT;- 您仍然可能会遇到奇怪的 SSMS 缓冲区问题,但它不应该经常发生。也不要打扰SET NOCOUNT OFF;- 总是有SET NOCOUNT ON;,句号。 -
由于这是一个巨大的表,您可能会考虑更改您在循环中设置@rowstogo 的方式。这样的事情将消除每次循环遍历该表的需要。 SET @rowstogo = @rowstogo - @@rowcount
-
我尝试了 SET @rowstogo = @rowstogo - @@rowcount,我认为它从删除触发器中获取了最后的行数并且给了我奇怪的结果。
-
您知道自己一次做 100 次,请改用 SET @rowstogo -= 100。至于你原来的问题。您是否有可以在 SQL Server 之外执行此操作的程序员? VB或C#中的东西?他们可以为此创造更好的用户体验。
-
这是我们的一位客户的数据清除/清理。唯一真正的用户是我。这个脚本将来可能会被重用,但它根本不是面向客户端的。我只需要一些方法来跟踪它在过程中的位置。 RaiseError 似乎运作良好。我添加了一个变量@NumberInBatch,这样我就不会与删除顶部 X 和 rowstogo-X 不同步。谢谢大家的帮助!
标签: sql sql-server while-loop