在 T-SQL 中为数据迁移保留干净的标识值块

Posted

技术标签:

【中文标题】在 T-SQL 中为数据迁移保留干净的标识值块【英文标题】:Reserving clean block of identity values in T-SQL for data migration 【发布时间】:2014-03-14 12:16:05 【问题描述】:

我们目前正在进行以下流程,其目标是在 2 组数据库服务器之间移动数据,同时维护 FK 并处理目标表已经包含具有重叠标识列值的行的事实:

    从“根”表及其所有子表的 FK 关联数据的 n 级深度以及可能驻留在源数据库服务器的同一实例上的其他数据库中的相关行中提取一组行。 将提取的数据集放置到目标数据库服务器上的一组临时表中。 通过为目标表保留标识块并更新所有相关的子暂存表来重新键入暂存表中的数据(这些暂存表中的每一个都将具有与源/目标表相同的架构,并添加了“lNewIdentityID " 列)。 以正确的顺序将具有新标识的数据插入到目标表中(显然将使用选项 SET IDENTITY_INSERT 'desttable' ON)。

我正在努力处理此过程的块保留部分 (#3)。我们的系统几乎是一个 24 小时系统,除了一个短的每周维护窗口。管理层需要此过程不必每周等待维护窗口在服务器之间迁移数据。话虽如此,我可能有 100 个插入事务与我们的迁移过程竞争,而它在 #3 上。下面是我试图保留身份块的尝试,但我担心在“SET @newIdent ...”和“DBCC CHECKIDENT ...”之间插入事务将完成而迁移过程不会在已知范围内有一个“干净”的身份块,可用于重新设置暂存数据的密钥。

我本质上需要锁定表,获取当前标识,增加标识,然后解锁表。我不知道如何在 T-SQL 中做到这一点,并且正在寻找想法。谢谢。

IF EXISTS (SELECT TOP 1 1 FROM sys.procedures WHERE [name]='DataMigration_ReserveBlock')
    DROP PROC DataMigration_ReserveBlock
GO

CREATE PROC DataMigration_ReserveBlock (
    @tableName varchar(100), 
    @blockSize int
)
AS
 BEGIN
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

    DECLARE @newIdent bigint;
    SET @newIdent = @blockSize + IDENT_CURRENT(@tableName);

    DBCC CHECKIDENT (@tableName, RESEED, @newIdent); 

    SELECT @newIdent AS NewIdentity;
 END
GO


DataMigration_ReserveBlock 'tblAddress', 1234

【问题讨论】:

【参考方案1】:

你可以把它包装在一个事务中

BEGIN TRANSACTION
...
COMMIT

它应该足够快,不会对您的其他插入过程造成问题。虽然包含 try / catch 逻辑是一个好主意,以便在出现问题时可以回滚。

【讨论】:

以上是关于在 T-SQL 中为数据迁移保留干净的标识值块的主要内容,如果未能解决你的问题,请参考以下文章

数据分析 - 单表简单查询

T-SQL 标识符

使用 JSON 对象展开 Pandas DataFrame 列

SQL Server笔记2

SQL学习之T-SQL编程之标识符变量批处理与运算符

T-SQL如何保留两位小数而不四舍五入[重复]