将 "normal" table 作为临时 table

Make a "normal" table as temporal table

我有一个 table 这样创建的:

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)
);

现在我希望能够保留此 table 的历史修改,所以我想将其设为临时 table。我知道创建临时table的脚本,最终结果应该是:

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));

最简单的方法就是删除之前的 table,然后使用良好的架构重新创建 table。

但是,我的table里面有很多资料,保存数据删除table,重新创建重新插入数据让我很不舒服table。

因此,如果您有在时间 table 中转换第一个 table 而无需删除所有内容并重新创建它的解决方案,那将是一个很大的帮助!

新建tableaddress_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