在有限的(1000 行)块中移动 SQL Server 数据

Move SQL Server data in limited (1000 row) chunks(在有限的(1000 行)块中移动 SQL Server 数据)
本文介绍了在有限的(1000 行)块中移动 SQL Server 数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个基于日期时间列归档 SQL Server 表中的行的进程.我想移动日期在 X 之前的所有行,但问题是每个日期有数百万行,所以对每个日期执行 BEGIN TRANSACTION...INSERT...DELETE...COMMIT 需要太长时间,并为其他用户锁定数据库.

I'm writing a process that archives rows from a SQL Server table based on a datetime column. I want to move all the rows with a date before X, but the problem is that there are millions of rows for each date, so doing a BEGIN TRANSACTION...INSERT...DELETE...COMMIT for each date takes too long, and locks up the database for other users.

有没有办法可以分小块做?也许使用 ROWCOUNT 或类似的东西?

Is there a way that I can do it in smaller chunks? Maybe using ROWCOUNT or something like that?

我最初考虑过这样的事情:

I'd originally considered something like this:

SET ROWCOUNT 1000

DECLARE @RowsLeft DATETIME
DECLARE @ArchiveDate DATETIME

SET @ROWSLEFT = (SELECT TOP 1 dtcol FROM Events WHERE dtcol <= @ArchiveDate)

WHILE @ROWSLEFT IS NOT NULL
BEGIN

    INSERT INTO EventsBackups
    SELECT top 1000 * FROM Events

    DELETE Events

    SET @ROWSLEFT = (SELECT TOP 1 dtcol FROM Events WHERE dtcol <= @ArchiveDate)

END

但后来我意识到我不能保证我正在删除的行是我刚刚备份的行.或者我可以...?

But then I realized that I can't guarantee that the rows I'm deleting are the ones I just backed up. Or can I...?

更新:我考虑过的另一个选项是添加一个步骤:

UPDATE: Another options I'd considered was adding a step:

  1. 将符合我的日期条件的前 1000 行选择到临时表中
  2. 开始交易
  3. 从临时表插入存档表
  4. 从源表中删除,跨列加入临时表
  5. 提交交易
  6. 重复 1-5 直到没有符合日期条件的行

有人知道这个系列的费用与下面讨论的其他一些选项相比如何吗?

Does anybody have an idea for how the expense of this series might compare to some of the other options discussed below?

详细信息:我正在使用 SQL 2005,因为有人问过.

DETAIL: I'm using SQL 2005, since somebody asked.

推荐答案

只需插入DELETE的结果:

Just INSERT the result of the DELETE:

WHILE 1=1
BEGIN

    WITH EventsTop1000 AS (
    SELECT TOP 1000 * 
        FROM Events
      WHERE <yourconditionofchoice>)
    DELETE EventsTop1000
        OUTPUT DELETED.* 
        INTO EventsBackup;

    IF (@@ROWCOUNT = 0)
        BREAK;
END

这是原子的和一致的.

这篇关于在有限的(1000 行)块中移动 SQL Server 数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Execute complex raw SQL query in EF6(在EF6中执行复杂的原始SQL查询)
Bulk insert with mysql2 and NodeJs throws 500(使用mysql2和NodeJS的大容量插入抛出500)
SSIS: Model design issue causing duplications - can two fact tables be connected?(SSIS:模型设计问题导致重复-两个事实表可以连接吗?)
SQL Server Graph Database - shortest path using multiple edge types(SQL Server图形数据库-使用多种边类型的最短路径)
Invalid column name when using EF Core filtered includes(使用EF核心过滤包括时无效的列名)
How should make faster SQL Server filtering procedure with many parameters(如何让多参数的SQL Server过滤程序更快)