zoukankan      html  css  js  c++  java
  • 迁移数据到历史表SQL(转)

    有时工作需要需要把当前表的数据,移到历史表中,而历史表基本是以时间(年)为后缀来命名历史表的,如 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  
  • 相关阅读:
    10-索引优化分析(2)
    09-索引优化分析(1)
    08-优化 SQL 步骤
    XHR 框架与 Dojo( xhrGet,xhrPut,xhrDelete)
    Win7窗口操作
    SQLServer游标详解
    Graham算法—二维点集VC++实现
    SQlserver表连接
    字符数组中将空格移到最后java实现
    笛卡儿积的java实现
  • 原文地址:https://www.cnblogs.com/s648667069/p/8251131.html
Copyright © 2011-2022 走看看