Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2005 对数百万行的更新查询将填充事务日志_Sql Server 2005_Tsql_Transaction Log - Fatal编程技术网

Sql server 2005 对数百万行的更新查询将填充事务日志

Sql server 2005 对数百万行的更新查询将填充事务日志,sql-server-2005,tsql,transaction-log,Sql Server 2005,Tsql,Transaction Log,作为下一个版本的一部分,我需要更新数百万行,但这样做会填充事务日志并失败。我有一些想法,但我不是SQL专家,所以我肯定会有一些我不知道的问题 相关要点: 我需要将一个脚本交给操作团队,因此需要一个不需要手动干预的T-SQL方法 显然,事务日志每15分钟被回收一次。(我考虑过在catch块中编写一个循环,使用waitfordelay'00:15:00',使用try-catch,如下所示) (编辑)除数据外,我无法修改任何内容 (编辑)这是一个简单的更新,将外键列更改为不同的现有键 谢谢 菲尔 声明

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

相关要点:

  • 我需要将一个脚本交给操作团队,因此需要一个不需要手动干预的T-SQL方法
  • 显然,事务日志每15分钟被回收一次。(我考虑过在catch块中编写一个循环,使用
    waitfordelay'00:15:00'
    ,使用try-catch,如下所示)
  • (编辑)除数据外,我无法修改任何内容
  • (编辑)这是一个简单的更新,将外键列更改为不同的现有键
  • 谢谢

    菲尔

    声明
    @受影响的
    设置@AffectedRows=0
    而@AffectedRows<@RowsToUpdate
    开始
    开始尝试
    开始训练
    --做一些更新
    设置@AffectedRows=@AffectedRows+@@RowCount
    提交传输
    结束尝试
    开始捕捉
    打印错误消息()
    等待延迟“00:15:00”
    端接
    结束
    打印@AffectedRows
    
    以下几点/想法:

  • 您可以将事务日志扩展到您想要的任何大小,这样它就不会填满它
  • 如果事务日志增长过快,您可以随时备份数据库并截断日志
  • 您可以批量处理数据(一次处理一百万个)
  • 您可以将数据复制到工作表中,然后在处理完成后将其重命名 以下几点/想法:

  • 您可以将事务日志扩展到您想要的任何大小,这样它就不会填满它
  • 如果事务日志增长过快,您可以随时备份数据库并截断日志
  • 您可以批量处理数据(一次处理一百万个)
  • 您可以将数据复制到工作表中,然后在处理完成后将其重命名
    您正在重新发明“啃食”删除/更新:)

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


    您正在重新发明一点一点的删除/更新:)

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


    最后,我写的例子效果最好;捕获中捕获到事务日志已满错误,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
    
    声明
    @受影响的
    设置@AffectedRows=0
    而@AffectedRows<@RowsToUpdate
    开始
    开始尝试
    开始训练
    --做一些更新
    设置@AffectedRows=@AffectedRows+@@RowCount
    提交传输
    结束尝试
    开始捕捉
    打印错误消息()
    等待延迟“00:15:00”
    端接
    结束
    打印@AffectedRows
    
    最后,我已经编写的示例效果最好;捕获中捕获到事务日志已满错误,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
    
    声明
    @受影响的
    设置@AffectedRows=0
    而@AffectedRows<@RowsToUpdate
    开始
    开始尝试
    开始训练
    --做一些更新
    设置@AffectedRows=@AffectedRows+@@RowCount
    提交传输
    结束尝试
    开始捕捉
    打印错误消息()
    等待延迟“00:15:00”
    端接
    结束
    打印@AffectedRows
    
    我忘了提到我不能进行任何形式的架构或管理类型更改。我更新了问题以反映这一点。你有关于成批执行更新的例子吗?@Phil这取决于表的架构,如果你有某种自然的方式告诉我们发生了更新或对表进行了分区,请编辑问题以包含架构和更新语句…我只是将一个ID更新为另一个ID,所以我用的是
    where-ID=@OldID
    @Phil,问题是如果你的PK在增加,那么你可以在PK在0+@I和100000+@I之间做,注意:您可能希望在每个批处理之后提交事务,否则您的事务日志将再次填满,并让您停留在第1方,基本上就像我在问题中的示例一样?我忘了提到我不能进行任何形式的架构或管理类型更改。我更新了问题以反映这一点。你有关于成批执行更新的例子吗?@Phil这取决于表的架构,如果你有某种自然的方式告诉我们发生了更新或对表进行了分区,请编辑问题以包含架构和更新语句…我只是将一个ID更新为另一个ID,所以我用的是
    where ID=@OldID
    @Phil,问题是如果你的PK在增加,那么你可以在PK在0+@I和100000+@I之间做,注意,你可能希望在每个批处理之后提交事务,否则你的事务日志会再次填满,并让你停留在第1方,基本上就像我在问题中的例子一样?好的,但我不担心并发性-我需要能够处理查询填充事务日志的情况。好的,但我不担心并发性-我需要能够处理查询填充事务日志的情况。