[英]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.