0

作为下一个版本的一部分,我需要更新数百万行,但这样做会填充事务日志并失败。我有一些想法,但我不是 SQL 专家,所以我确信会有一些我不知道的问题。

相关点:

  1. 我需要将一个脚本交给运营团队,因此需要一个无需人工干预的 T-SQL 方法。
  2. 显然,事务日志每 15 分钟被回收一次。WAITFOR DELAY '00:15:00'(我考虑过在 catch 块中编写一个带有 try-catch 的循环,如下所示)
  3. (编辑)除了数据我不能修改任何东西。
  4. (编辑)这是一个简单的更新,将外键列更改为不同的现有键。

谢谢,

菲尔

DECLARE
    @AffectedRows int

SET @AffectedRows = 0

WHILE @AffectedRows < @RowsToUpdate
BEGIN
    BEGIN TRY
        BEGIN TRAN
        -- Do some updates  
        SET @AffectedRows = @AffectedRows + @@RowCount
        COMMIT TRAN
    END TRY
    BEGIN CATCH
        PRINT ERROR_MESSAGE()
        WAITFOR DELAY '00:15:00'
    END CATCH
END

PRINT @AffectedRows
4

3 回答 3

2

最后,我已经编写的示例效果最好;事务日志已满错误被捕获,并且 15 分钟足以回收日志。

DECLARE 
    @AffectedRows int 

SET @AffectedRows = 0 

WHILE @AffectedRows < @RowsToUpdate 
BEGIN 
    BEGIN TRY 
        BEGIN TRAN 
        -- Do some updates   
        SET @AffectedRows = @AffectedRows + @@RowCount 
        COMMIT TRAN 
    END TRY 
    BEGIN CATCH 
        PRINT ERROR_MESSAGE() 
        WAITFOR DELAY '00:15:00' 
    END CATCH 
END 

PRINT @AffectedRows
于 2010-06-22T11:45:18.393 回答
1

几点/想法:

  1. 您可以将事务日志扩展到您想要的任何大小,这样它就不会填满它。
  2. 如果您的事务日志增长太多,您可以随时备份您的数据库并截断日志。
  3. 您可以批量处理数据(一次处理一百万个)
  4. 您可以将数据复制到工作表,然后在处理完成后将其 sp_rename。
于 2010-06-21T10:14:27.163 回答
0

您正在重新发明蚕食删除/更新:)

看看这种方法,你可以做比单行更大的块:

http://www.sqlservervideos.com/video/nibbling-deletes/

http://sqladvice.com/blogs/repeatableread/archive/2005/09/20/12795.aspx

于 2010-06-21T10:23:03.543 回答