Как скопировать тип метки времени - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть таблица со столбцом TIMESTAMP:

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

когда я копирую строки из одной таблицы в другую, используя:

SELECT * INTO EX_EMPLOYEE_T 
    FROM EX_EMPLOYEE 
    WHERE 1=0

или

INSERT INTO EX_EMPLOYEE_T
    SELECT * 
        FROM EX_EMPLOYEE

Я получаю это предупреждение:

Предупреждение. Пользователь не может вставить ненулевое значение в столбец TIMESTAMP. Вместо этого в поле TIMESTAMP вставлено значение отметки времени базы данных.

Столбец TIMESTAMP в целевой таблице заменяется текущей отметкой времени базы данных.

Мой вопрос
Как скопировать строки со столбцом TIMESTAMP, сохранив значение TIMESTAMP из исходной таблицы?

(Есть ли настройка, аналогичная SET IDENTITY ON/OFF)

Мой сценарий
У меня есть 2 таблицы, одна для «живых» данных, а другая для «резервного копирования», поэтому мне нужно скопировать строки с неповрежденным TIMESTAMP. Мне нужно, чтобы он был неповрежденным, чтобы определить, произошло ли изменение в «живой» строке.

1 Ответ

0 голосов
/ 06 сентября 2018

Сервер репликации Sybase (теперь SAP) (SRS) может реплицировать значения меток времени между таблицами Sybase / SAP ASE, т. Е. Обработчик SRS может вставлять явные значения в столбец типа timestamp.

КакЭто возможно?Существует несколько требований:

  • пользователь, выполняющий вставку (в столбец timestamp), должен иметь роль replication_role (и она должна быть активной)
  • youнеобходимо выполнить команду set timestamp_insert on (ПРИМЕЧАНИЕ: это приведет к ошибке, если у вашего пользователя нет replication_role)
  • , вам нужно явно перечислить столбцы целевой таблицы в операторе вставки

Настройка:

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.

...