简体   繁体   English

将数据从一个表移动到另一个 SQL 服务器的最佳方法

[英]Best way to move data from one table to another SQL Server

I have eight tables that I need to move data from one table to another for archive & data retention reasons.我有八个表,出于存档和数据保留的原因,我需要将数据从一个表移动到另一个表。 I am not the best at stored procedures so I am looking for ideas and best practices for moving data - even if it it means starting over from scratch.我不是最擅长存储过程的,所以我正在寻找移动数据的想法和最佳实践——即使这意味着从头开始。 I'm sure I am doing something wrong but I am willing to learn.我确定我做错了什么,但我愿意学习。

My current T-SQL Code:我当前的 T-SQL 代码:

USE [SPCTST]
GO

/****** Object:  StoredProcedure [dbo].[sp_Insert_Data_Into_Archive_Tables]    Script Date: 5/10/2022 11:27:33 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO




/* =============================================
 Author:        Eric Brenner
 Create date:   3/3/2022
 Description:   Moves data from the ACTIVE tables
                to the ARCHIVE tables based on the 
                ARCHIVE_DATETIME below.

 Updates:       Added DELETE statement just after
                inserting records into the ARCHIVE
                tables.

 5/9/2022:      Removed EXCEPT clause, added
                seperate BEGIN and COMMIT
                clauses, and TRY statements.
 ============================================= */

ALTER PROCEDURE [dbo].[sp_Insert_Data_Into_Archive_Tables]
    --@Archive_Months tinyint -- Use this as a parameter if desired in the future. Currently disabled.
AS
    -- @ARCHIVE_DATETIME is a variable to contain the number of months worth of data you want to keep in the ARCHIVE table(s).
    DECLARE @ARCHIVE_DATETIME datetime = DATEADD(month, -26, DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0)) -- a little over 2 years

    -- Convert Date to a 16-digit string to use against because of the db design
    DECLARE @ARCHIVE_DATETIME_GS nvarchar(16) = CONCAT(YEAR(@ARCHIVE_DATETIME), --year
                                FORMAT(@ARCHIVE_DATETIME,'MM'), --month
                                FORMAT(@ARCHIVE_DATETIME,'dd'), --day
                                '00000000')
    
    -- If the temporary table 'DateTimeValues' exists, remove it
    IF OBJECT_ID('TEMPDB..#DateTimeValues') IS NOT NULL
    BEGIN
        DROP TABLE #DateTimeValues
    END
    
    -- Insert data into the Archive Tables
    BEGIN
        BEGIN TRY
            BEGIN TRANSACTION;
                INSERT INTO OC_VNOTE_ARCHIVE
                    SELECT * FROM OC_VNOTE WHERE OC_VNOTE.DATETIME < @ARCHIVE_DATETIME_GS
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH

        BEGIN TRY
            BEGIN TRANSACTION;
                DELETE FROM OC_VNOTE WHERE OC_VNOTE.DATETIME < @ARCHIVE_DATETIME_GS;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH
    END

    BEGIN
        BEGIN TRY
            BEGIN TRANSACTION;
                INSERT INTO OC_VMON_AUX_ARCHIVE
                    SELECT * FROM OC_VMON_AUX WHERE OC_VMON_AUX.DATETIMEAUX < @ARCHIVE_DATETIME_GS;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH

        BEGIN TRY
            BEGIN TRANSACTION;
                DELETE FROM OC_VMON_AUX WHERE OC_VMON_AUX.DATETIMEAUX < @ARCHIVE_DATETIME_GS;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH
    END

    BEGIN
        BEGIN TRY
            BEGIN TRANSACTION;
                INSERT INTO OC_VMON_ARCHIVE
                    SELECT * FROM OC_VMON WHERE OC_VMON.DATETIME < @ARCHIVE_DATETIME_GS;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH

        BEGIN TRY
            BEGIN TRANSACTION;
                DELETE FROM OC_VMON WHERE OC_VMON.DATETIME < @ARCHIVE_DATETIME_GS;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH
    END

    BEGIN
        BEGIN TRY
            BEGIN TRANSACTION;
                INSERT INTO OC_VDAT_AUX_ARCHIVE
                    SELECT * FROM OC_VDAT_AUX WHERE OC_VDAT_AUX.DATETIMEAUX < @ARCHIVE_DATETIME_GS;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH

        BEGIN TRY
            BEGIN TRANSACTION;
                DELETE FROM OC_VDAT_AUX WHERE OC_VDAT_AUX.DATETIMEAUX < @ARCHIVE_DATETIME_GS;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH
    END

    BEGIN
        BEGIN TRY
            BEGIN TRANSACTION;
                INSERT INTO OC_VDATA_ARCHIVE
                    SELECT * FROM OC_VDATA WHERE OC_VDATA.DATETIME < @ARCHIVE_DATETIME_GS;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH

        BEGIN TRY
            BEGIN TRANSACTION;
                DELETE FROM OC_VDATA WHERE OC_VDATA.DATETIME < @ARCHIVE_DATETIME_GS;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH
    END

    --------------------------------------------------------------------------------------------------------------------

    BEGIN
        BEGIN TRY
            BEGIN TRANSACTION;
                INSERT INTO OC_DNOTE_ARCHIVE_PC
                    SELECT * FROM OC_DNOTE_PC WHERE OC_DNOTE_PC.DATETIME < @ARCHIVE_DATETIME_GS;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH

        BEGIN TRY
            BEGIN TRANSACTION;
                DELETE FROM OC_DNOTE_PC WHERE OC_DNOTE_PC.DATETIME < @ARCHIVE_DATETIME_GS;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH
    END

    BEGIN
        BEGIN TRY
            BEGIN TRANSACTION;
                INSERT INTO OC_DDAT_AUX_ARCHIVE_PC
                    SELECT * FROM OC_DDAT_AUX_PC WHERE OC_DDAT_AUX_PC.DATETIMEAUX < @ARCHIVE_DATETIME_GS;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH

        BEGIN TRY
            BEGIN TRANSACTION;
                DELETE FROM OC_DDAT_AUX_PC WHERE OC_DDAT_AUX_PC.DATETIMEAUX < @ARCHIVE_DATETIME_GS;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH
    END

    BEGIN
        BEGIN TRY
            BEGIN TRANSACTION;
                INSERT INTO OC_DDATA_ARCHIVE_PC
                    SELECT * FROM OC_DDATA_PC WHERE OC_DDATA_PC.DATETIME < @ARCHIVE_DATETIME_GS;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH

        BEGIN TRY
            BEGIN TRANSACTION;
                DELETE FROM OC_DDATA_PC WHERE OC_DDATA_PC.DATETIME < @ARCHIVE_DATETIME_GS;
            COMMIT TRANSACTION;
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION;
        END CATCH
    END

GO

First you do not need to have all those TRY CATCH in your code.首先,您不需要在代码中包含所有这些 TRY CATCH。 Only one will be sufficient with this code :此代码只有一个就足够了:

BEGIN CATCH
   IF XACT_STATE()<> 0
      ROLLBACK;
   THROW;
END CATCH 

Second , you can use partition to switch sets of rows from one table to another by a simple "SWITCH PARTITION ... " command that will act on all your table is they have the same partition parameter (which seems to be the case with the DTATIME column...其次,您可以使用分区通过一个简单的“SWITCH PARTITION ...”命令将一组行从一个表切换到另一个表,该命令将对您的所有表起作用,如果它们具有相同的分区参数(这似乎与DTATIME 列...

Third you can do a transaction on each couple of INSERT/DELETE to minimize the transaction log growth第三,您可以在每对 INSERT/DELETE 上执行一个事务,以最大限度地减少事务日志增长

Bit late but... Just do It in 1 go, set db in simple recovery if possible;有点晚了,但是...只要在 1 go 中执行,如果可能的话,将数据库设置为简单恢复; keep batches small to avoid growth of logfile.保持小批量以避免日志文件的增长。 This code will roll back completely in case of failure如果失败,此代码将完全回滚

DELETE FROM OC_VNOTE OUTPUT deleted.* INTO OC_VNOTE_ARCHIVE WHERE OC_VNOTE.DATETIME < @ARCHIVE_DATETIME_GS;从 OC_VNOTE 中删除 OUTPUT 已删除。* 进入 OC_VNOTE_ARCHIVE,其中 OC_VNOTE.DATETIME < @ARCHIVE_DATETIME_GS;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 每晚将数据从一个表移动到另一个表 - Move data from one table to another every night SQL server 将 SQL 数据从一个表移动到另一个表 - Move SQL data from one table to another 从一个表返回数据以及从另一个表映射数据的SQL最佳方法 - SQL Best way to return data from one table along with mapped data from another table 使用另一个SQL Server的数据更新一个SQL Server的最佳方法? - Best way to update one SQL Server with data from another SQL Server? 将所选数据从一个服务器移动到另一个sql server 2008 - Move selected data from one server to another sql server 2008 将一个或多个表从一台 SQL 服务器传输到另一台服务器的最佳方法是什么? - What is the best way to transfer a table or tables from one SQL server to another? 在SQL Server 2008中通过检查将varbinary从一个表移动到另一个表 - Move a varbinary from one table to another with a check in SQL Server 2008 数据从sql服务器中的一个表移动到另一个表时的精度提高 - precision gains where data move from one table to another in sql server 在SQL中从另一个表更新一个表的最佳方法是什么? - What is the best way to update a one table from another in SQL? 从一个表或另一个表中选择数据的最佳方法 - best way to select data from one table or another
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM