如何复制时间戳数据类型

How to Copy a Timestamp Datatype

我有一个 table 和 TIMESTAMP 列:

create  table dbo.EX_EMPLOYEE (
    NAME_X            varchar(10) null,
    RECORD_TIME_STAMP timestamp   null
    )

当我将行从一个 table 复制到另一个时,使用以下任一方法:

SELECT * INTO EX_EMPLOYEE_T 
    FROM EX_EMPLOYEE 
    WHERE 1=0

或:

INSERT INTO EX_EMPLOYEE_T
    SELECT * 
        FROM EX_EMPLOYEE

我收到此警告:

Warning: A non-null value cannot be inserted into a TIMESTAMP column by the user. The database timestamp value has been inserted into the TIMESTAMP field instead.

目标 table 中的 TIMESTAMP 列替换为当前数据库时间戳。

我的问题
如何复制具有 TIMESTAMP 列的行,同时保留源 table 中的 TIMESTAMP 值?

(有没有类似SET IDENTITY ON/OFF的设置)

我的场景
我有 2 个 table,一个用于 "live" 数据,另一个用于 "backup",所以我需要完整地复制 TIMESTAMP 的行。我需要它完好无损,以便检测 "live" 行是否发生了变化。

Sybase(现在的 SAP)复制服务器 (SRS) 可以在 Sybase/SAP ASE table 之间复制时间戳值,即 SRS 维护用户可以将显式值插入 [= 类型的列中12=].

这怎么可能?有几点要求:

  • 执行插入(到 timestamp 列)的用户必须具有 replication_role 角色(并且必须处于活动状态)
  • 您需要发出 set timestamp_insert on 命令(注意:如果您的用户没有 replication_role,这将产生错误)
  • 您需要在插入语句中明确列出目标 table 的列

设置:

exec sp_displaylogin
go
...
Configured Authorization:
        ...
        replication_role (default ON)      <<<=== verify role assigned and active
        ...

create table EX_EMPLOYEE
(NAME_X                 varchar(10)     NULL
,RECORD_TIME_STAMP      timestamp       NULL
)
go

insert into EX_EMPLOYEE (NAME_X) values ('Larry')
insert into EX_EMPLOYEE (NAME_X) values ('Mo')
insert into EX_EMPLOYEE (NAME_X) values ('Curly')
go

select * from EX_EMPLOYEE
go

 NAME_X     RECORD_TIME_STAMP
 ---------- ------------------
 Larry      0x00000000ec4304fa
 Mo         0x00000000ec4304fd
 Curly      0x00000000ec430501

select * into EX_EMPLOYEE_T FROM EX_EMPLOYEE where 1=2
go

现在进行一些插入测试...

-- haven't issued the 'set timestamp_insert on' commmand, yet

insert into EX_EMPLOYEE_T
select * from EX_EMPLOYEE
go

Warning: A non-null value cannot be inserted into a TIMESTAMP column by the user. The database timestamp value has been inserted into the TIMESTAMP field instead.

-- received the *WARNING*, ie, rows are inserted but they receive new timestamp values

select * from EX_EMPLOYEE_T
go

 NAME_X     RECORD_TIME_STAMP
 ---------- ------------------
 Larry      0x00000000ec430548       <<<=== different from what's in EX_EMPLOYEE
 Mo         0x00000000ec43054a       <<<=== different from what's in EX_EMPLOYEE
 Curly      0x00000000ec43054c       <<<=== different from what's in EX_EMPLOYEE

-- enable direct insert of timestamp values

set timestamp_insert on
go

truncate table EX_EMPLOYEE_T
go

-- w/out explicitly listing target columns ...

insert into EX_EMPLOYEE_T
select * from EX_EMPLOYEE
go

-- no warning message is generated, insert succeeds, but new timestamp values are generated

select * from EX_EMPLOYEE_T
go

 NAME_X     RECORD_TIME_STAMP
 ---------- ------------------
 Larry      0x00000000ec430555       <<<=== different from what's in EX_EMPLOYEE
 Mo         0x00000000ec430557       <<<=== different from what's in EX_EMPLOYEE
 Curly      0x00000000ec430559       <<<=== different from what's in EX_EMPLOYEE

truncate table EX_EMPLOYEE_T
go

-- this time we'll explicitly list the target table's columns ...

insert into EX_EMPLOYEE_T (NAME_X, RECORD_TIME_STAMP)
select * from EX_EMPLOYEE
go

-- and now we see the timestamp values copied from the source

select * from EX_EMPLOYEE_T
go

 NAME_X     RECORD_TIME_STAMP
 ---------- ------------------
 Larry      0x00000000ec4304fa       <<<=== same as what's in EX_EMPLOYEE
 Mo         0x00000000ec4304fd       <<<=== same as what's in EX_EMPLOYEE
 Curly      0x00000000ec430501       <<<=== same as what's in EX_EMPLOYEE

以上是在 ASE 15.7 SP138 数据服务器上测试的。