【问题标题】:Make a "normal" table as temporal table将“正常”表作为临时表
【发布时间】:2021-04-11 13:36:53
【问题描述】:

我有一个这样创建的表:

CREATE TABLE address_user 
(
    [username] VARCHAR(13) NOT NULL,
    [address] CHAR(58) NOT NULL,
    [id] BIGINT NOT NULL,

    CONSTRAINT [PK_ address_user] 
        PRIMARY KEY CLUSTERED ([id] ASC)
);

现在我希望能够保留这个表的历史修改,所以我想把它做成临时表。我知道创建临时表的脚本,最终结果应该是:

CREATE TABLE address_user 
(
    [username] VARCHAR(13) NOT NULL,
    [address] CHAR(58) NOT NULL,
    [id] BIGINT NOT NULL,
    [sys_start_time] DATETIME2(7) 
        GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
    [sys_end_time] DATETIME2 (7) 
        GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,

    PERIOD FOR SYSTEM_TIME ([sys_start_time], [sys_end_time]),
    CONSTRAINT [PK_ address_user] 
        PRIMARY KEY CLUSTERED ([id] ASC)
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE=[dbo].[address_user_history], DATA_CONSISTENCY_CHECK=ON));

执行此操作的简单方法是删除之前的表,然后使用良好的架构重新创建表。

但是,我的表中有很多信息,保存数据并删除表,重新创建并重新插入数据让我很不舒服。

因此,如果您有解决方案来转换临时表中的第一个表,而无需删除所有内容并重新创建它,那应该会有很大帮助!

【问题讨论】:

    标签: sql-server temporal-tables


    【解决方案1】:

    创建新表address_user_new,插入数据,然后使用sp_renameaddress_user重命名为address_user_old,将address_user_new重命名为address_user。这一切都可以在事务中完成,以确保转换是原子的并且明显是瞬时的。例如

    if object_id('address_user') is not null
      ALTER TABLE address_user SET ( SYSTEM_VERSIONING = OFF)
    go
    if object_id('address_user_new') is not null
      ALTER TABLE address_user_new SET ( SYSTEM_VERSIONING = OFF)
    go
    drop table if exists address_user
    drop table if exists address_user_history
    drop table if exists address_user_new
    drop table if exists address_user_old
    go
    
    CREATE TABLE address_user 
    (
        [username] VARCHAR(13) NOT NULL,
        [address] CHAR(58) NOT NULL,
        [id] BIGINT NOT NULL,
    
        CONSTRAINT [PK_address_user] 
            PRIMARY KEY CLUSTERED ([id] ASC)
    );
    
    go
    CREATE TABLE address_user_new 
    (
        [username] VARCHAR(13) NOT NULL,
        [address] CHAR(58) NOT NULL,
        [id] BIGINT NOT NULL,
        [sys_start_time] DATETIME2(7) 
            GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
        [sys_end_time] DATETIME2 (7) 
            GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
    
        PERIOD FOR SYSTEM_TIME ([sys_start_time], [sys_end_time]),
        CONSTRAINT [PK_address_user_new] 
            PRIMARY KEY CLUSTERED ([id] ASC)
    )
    WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE=[dbo].[address_user_history], DATA_CONSISTENCY_CHECK=ON));
    
    go
    
    
    set xact_abort on
    begin transaction
    
    insert into address_user_new(username,address,id)
    select username,address,id
    from address_user with (tablockx)
    
    exec sp_rename 'address_user', 'address_user_old', 'OBJECT'
    exec sp_rename 'PK_address_user', 'PK_address_user_old', 'OBJECT'
    
    exec sp_rename 'address_user_new', 'address_user', 'OBJECT'
    exec sp_rename 'PK_address_user_new', 'PK_address_user', 'OBJECT'
    
    commit transaction
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-17
      • 1970-01-01
      • 2014-01-20
      • 2012-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多