有时工作需要需要把当前表的数据,移到历史表中,而历史表基本是以时间(年)为后缀来命名历史表的,如 A_2011,A_2012,在移数据时,要按数据的时间,移到不同的表中,且由于如果数据有同步。一次处理的数据不能太大。否则同步链会被Block.所以需要批理处理。

下面是一个通用的写法,可以作为参考!(这个应该是出自邹建大侠之手,因为需要写这样的处理,去找了下类似代码,找到的)

[sql] view plain copy

    -- row batch:               100
-- row Process limit: 50000
-- data keep days: 90
-- */
CREATE PROCEDURE dbo.TransferNInvoiceToHistoryBeforeDay
@FromDate char(10)
AS
SET NOCOUNT ON; -- current trancount
DECLARE
@__trancount int;
SELECT
@__trancount = @@TRANCOUNT; BEGIN TRY
DECLARE
@row_batch int,
@row_limit int,
@row_process int,
@row_count int,
@date_begin datetime,
@date_end datetime; -- row batch and data keep date
SELECT
@row_batch = 100, -- each batch process rows
@row_limit = 50000, -- total row process limit
@date_end = @FromDate,--DATEDIFF(Day, 90, GETDATE()), -- process top date
@row_process = 0; -- process rows total -- ===========================================
-- get process begin date and rows
SELECT
@date_begin = MIN(InvoiceDate),
@row_count = COUNT(*)
FROM 需要处理的当前表名 WITH(NOLOCK)
WHERE InvoiceDate < @date_end; IF @row_count = 0
RETURN;
ELSE IF @date_begin IS NULL
BEGIN
RAISERROR(N'column InvoiceDate include NULL value, please fix it', 16, 1)
END IF @row_limit IS NULL OR @row_limit <= 0
SET @row_limit = @row_count; RAISERROR('%d rows need process, current process limit %d rows', 10, 1, @row_count, @row_limit) WITH NOWAIT -- ===========================================
-- process by year
DECLARE
@date datetime;
SET @date = @date_begin; WHILE @row_process < @row_limit
AND @date < @date_end
BEGIN
-- process date and sql
DECLARE
@sql nvarchar(4000),
@_date_begin datetime,
@_date_end datetime; SELECT
@_date_begin = @date,
@_date_end = CASE
WHEN DATEDIFF(Year, @_date_begin, @date_end) = 0 THEN @date_end
ELSE DATEADD(Year, YEAR(@_date_begin) - 1899, 0)
END,
@date = @_date_end,
@row_count = @row_batch,
@sql = N'
DECLARE @tb_id TABLE(
invoiceNumber int
PRIMARY KEY
);
INSERT @tb_id
SELECT TOP(@row_batch)
invoiceNumber
FROM Nact.dbo.NewEgg_InvoiceMaster A
WHERE InvoiceDate >= @_date_begin
AND InvoiceDate < @_date_end; DELETE A
OUTPUT deleted.*
INTO 历史表名不带时间部份' + RTRIM(Year(@_date_begin)) + N'
FROM 当前表名 A,
@tb_id B
WHERE A.invoiceNumber = B.invoiceNumber;
'; -- ===========================================
-- process by batch for year
WHILE @row_process < @row_limit
AND @row_count = @row_batch
BEGIN
-- move data
IF @__trancount = 0
BEGIN TRAN;
ELSE
SAVE TRAN __TRAN_SavePoint; EXEC sys.sp_executesql
@sql,
N'
@row_batch int,
@_date_begin datetime,
@_date_end datetime
',
@row_batch, @_date_begin, @_date_end; SELECT
@row_count = @@ROWCOUNT,
@row_process = @row_process + @row_count; IF XACT_STATE() = 1 AND @__trancount = 0
COMMIT;
END
END IF @__trancount = 0
BEGIN
IF XACT_STATE() = -1
ROLLBACK TRAN;
ELSE
BEGIN
WHILE @@TRANCOUNT > 0
COMMIT TRAN;
END
END
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0
BEGIN
IF @__trancount = 0
ROLLBACK TRAN;
ELSE IF XACT_STATE() = 1 AND @@TRANCOUNT > @__trancount
ROLLBACK TRAN __TRAN_SavePoint;
END DECLARE
@__error_number int,
@__error_message nvarchar(2048),
@__error_severity int,
@__error_state int,
@__error_line int,
@__error_procedure nvarchar(126),
@__user_name nvarchar(128),
@__host_name nvarchar(128); SELECT
@__error_number = ERROR_NUMBER(),
@__error_message = ERROR_MESSAGE(),
@__error_severity = ERROR_SEVERITY(),
@__error_state = ERROR_STATE(),
@__error_line = ERROR_LINE(),
@__error_procedure = ERROR_PROCEDURE(),
@__user_name = SUSER_SNAME(),
@__host_name = HOST_NAME(); RAISERROR(
N'User: %s, Host: %s, Procedure: %s, Error %d, Level %d, State %d, Line %d, Message: %s ',
@__error_severity,
1,
@__user_name,
@__host_name,
@__error_procedure,
@__error_number,
@__error_severity,
@__error_state,
@__error_line,
@__error_message);
END CATCH GO

迁移数据到历史表SQL(转)的更多相关文章

  1. MySQL存储过程-->通过游标遍历和异常处理迁移数据到历史表

    -- 大表数据迁移,每天凌晨1点到5点执行,执行间隔时间10分钟,迁移旧数据到历史表. DELIMITER $$ USE `dbx`$$ DROP PROCEDURE IF EXISTS `pro_x ...

  2. oracle数据向历史表数据迁移————procedure

    create or replace procedure remove_refund_his_pro isbegin declare cursor refund_query_cur is select ...

  3. vertica从其它表迁移数据到新表(insert into 语句使用方法实例)

    版权声明:本文为博主原创文章.博主同意自由转载. https://blog.csdn.net/tx18/article/details/26585649 #例:迁移微博用户数据. 因为源表weiboF ...

  4. 通过现有数据导出新表SQL

    Date: 20140217 Auth: JIN 需求: 导出一个表的两个列的表的SQL语句(包含数据) 方法:创立一个临时表 mysql> desc kw_keywords;+-------- ...

  5. SQLSERVER 数据调度示例,调度数据到中间表或者历史表

    USE [MeiDongPay_Test] GO /****** Object: StoredProcedure [dbo].[Job_BatchTransferOrderToMidst] Scrip ...

  6. Mysql存储过程历史表备份

    应用背景 SCADA采集系统需要将实时数据存入历史表.问题1:如何更简单的添加历史数据?2.海量历史数据,比如年数据,如何快速筛选 画曲线? 利用mysql的事件,每小时存一次采集数据: 每月备份历史 ...

  7. SQL Server ->> 深入探讨SQL Server 2016新特性之 --- Temporal Table(历史表)

    原文:SQL Server ->> 深入探讨SQL Server 2016新特性之 --- Temporal Table(历史表) 作为SQL Server 2016(CTP3.x)的另一 ...

  8. mysql 案例 ~ 表空间迁移数据与数据导入

    一  简介:mysql5.6+的表空间传输二 目的:复制数据到另一个表三 步骤   1 create table b like a ->创建一个空表   2 alter table b disc ...

  9. sql server迁移数据(文件组之间的互相迁移与 文件组内文件的互相迁移)

    转自:https://www.cnblogs.com/lyhabc/p/3504380.html?utm_source=tuicool SQLSERVER将数据移到另一个文件组之后清空文件组并删除文件 ...

随机推荐

  1. MySQL优化Explain命令简介(一)

    最近碰到MySQL需要写入大量数据并查询的场景,于是学习了一下MySQL的查询优化,想找关于explain命令的详细资料,然而网上并没有找全,最后终于在<高性能MySQL>中找到了对这一命 ...

  2. hadoop hdfs 找不到本地库解决办法

    export LD_LIBRARY_PATH=/usr/lib/hadoop-0.20-mapreduce/lib/native/Linux-amd64-64 <-- HAOOP_HOME/li ...

  3. C# webapi 路由规则和接收数据

    1:新建的web api项目 默认的访问api方式:  (get,post,delect,put)  api+控制器  以Post为例子 post提交单个参数: 接收方法  post提交多个参数  接 ...

  4. python全栈开发-前方高能-函数

    python_day_9 一.今日主要内容 函数: 函数:对功能的封装 语法: def 函数名(形参): 函数体 函数名(实参) 函数名:命名规则和变量一样 函数的返回值: return, 函数执行完 ...

  5. python4 - 字典

    字典 定义:字典是无序的,它不能通过偏移来存取,只能通过键来存取. 特点:内部没有顺序,通过键来读取内容,可嵌套,方便我们组织多种数据结构,并且可以原地修改里面的内容,属于可变类型. 创建字典.{}, ...

  6. php常用的几个预定义变量

    __FILE__:返回所在路径文件名和文件名称 __DIR__:返回文件所在的完整目录 __LINE__:返回当前文件代码的行号 __CLASS__:返回当前类名 __FUNCTION__:返回当前方 ...

  7. 使用PHP写ajax接口

    使用PHP写ajax接口 之前有学过php都是前后端没有分离的,所以也想去了解后端是怎么写出ajax接口的,可能问了别人或者上网找了很多资料都很有有点懵,或者说直接用TP或者lavarel这些后端框架 ...

  8. windows中使用mysql配置my.ini时的坑

    windows中安装mysql的一般步骤: mysql版本:5.7.16 1.解压 2.把解压的文件夹bin目录地址添加到环境变量PATH里面 3.在文件加中添加配置文件my.ini——配置内容后面说 ...

  9. QSS 样式示例:QTreeWidget, QComboBox,QSlider,QSpinBox

    目录 Image 填充整个控件的区域 QTreeWidget QSpinbox 的上翻下翻按钮和箭头 QComboBox 的设置,大坑 QSlider 最近需要对一个软件加上Qt界面和 的样式,第一次 ...

  10. Pvmove中断后恢复LV状态

    Pvmove中断后恢复LV状态   pvmove执行时关闭中断窗口后,pvmove进程会被强制杀掉,从而导致lv的状态异常,无法重新进行pvmove和其他lvm镜像增加相关操作,可以通过如下方式修复: ...