数据库迁移 - 可以多次运行的UTC转换脚本

时间:2011-09-15 18:59:14

标签: tsql migration

我正在编写一个脚本,将日期时间列从服务器时间转换为UTC时间。我有一个执行此操作的函数,但是,迁移脚本将作为具有以下约束的较大进程的一部分运行:

  1. 脚本必须能够多次运行(即不要将列转换两次)
  2. 迁移后无法保留临时表或其他数据
  3. 到目前为止这是脚本:

    SET XACT_ABORT ON;
    
    BEGIN TRANSACTION;
    
    UPDATE SOME_TABLE
    SET LastModified = [dbo].[f_ServerToUTC]( LastModified )
    
    COMMIT TRANSACTION;
    

    由于毫秒在我的场景中并不重要,我考虑将毫秒部分设置为某个特定值,表明已经执行了迁移。但是,我觉得在未转换的数据中遇到此值的概率太高(给定的足够)。

    根据我的约束,还有其他方法可以表明脚本已经运行了吗?

1 个答案:

答案 0 :(得分:2)

我们解决这个问题的方式对我们的系统来说有些特别,但对其他人可能有用。我们有一个用户定义的类型UtcDateTime,定义为:

CREATE TYPE [dbo].[UtcDateTime] FROM [datetime] NOT NULL

由于我们将列更新为UTC而不是服务器时间,因此更改数据类型也是有意义的。因此,我们可以检查列上是否已更改数据类型,以防止多次运行转换。

IF NOT EXISTS(
    SELECT 1
    FROM sys.tables t
    INNER JOIN sys.columns c
        ON t.object_id = c.object_id
    INNER JOIN sys.types ty
        ON c.user_type_id = ty.user_type_id
    WHERE t.object_id = object_id( 'SOME_TABLE' )
        AND c.name = 'LastModified'
        AND ty.name = 'utcdatetime'
)
BEGIN

    SET XACT_ABORT ON;

    BEGIN TRANSACTION;

    ALTER TABLE SOME_TABLE
        ALTER COLUMN [LastModified] UTCDATETIME

    UPDATE SOME_TABLE
    SET LastModified = [dbo].[f_ServerToUTC]( LastModified )

    COMMIT TRANSACTION;

END