Инкремент SQL RowVersion перед увеличением данных в Trigger
Я только начал использовать RowVersion в T-SQL и заметил кое-что очень интересное. Я создал Proc для обновления таблицы со столбцом RowVersion, и в конце этого процесса я распечатываю представление RowVersion для удобочитаемой даты. Я также добавил триггер, который обновляет данные в таблице и печатает RowVersion до и после. Это дало некоторые интересные результаты...
Из Insert Proc после вставки данных = 1900-01-01 05: 43: 13.373
От запуска триггера до того, как мы изменим какие-либо данные = 1900-01-01 05: 43: 13.377
От конца триггера после изменения данных = 1900-01-01 05: 43: 13.377
Начало значения триггера для столбца RowVersion изменилось с конца значения proc для столбца RowVersion, несмотря на тот факт, что мы еще не добавили никаких данных. Это также как конец триггера. Почему это? Это как-то связано с последовательностью выполнения операторов SQL? Любая помощь в понимании этого будет принята с благодарностью. Процесс и триггер перечислены ниже:
CREATE PROCEDURE [dbo].[TestRowVersionProc]
AS
INSERT INTO TestRowversion (ID, Number)
VALUES ('6', '6')
DECLARE @rv DATETIME
SELECT @rv = GenerationNumber FROM TestRowversion WHERE ID = '6'
SELECT CONVERT(VARCHAR(50), @rv , 121)
GO
CREATE TRIGGER [dbo].[TestRowversion_AfterInsertUpdate] ON [dbo].[TestRowversion] AFTER INSERT,UPDATE
AS
if @@rowcount = 0 return
set nocount on
DECLARE @rv DATETIME
SELECT @rv = GenerationNumber FROM TestRowversion WHERE ID = '6'
SELECT CONVERT(VARCHAR(50), @rv , 121)
DECLARE @Id NVARCHAR(1)
SELECT @Id = ID FROM inserted
UPDATE TestRowversion
SET Number = 'FromTrigger'
WHERE ID = '6'
SELECT @rv = GenerationNumber FROM TestRowversion WHERE ID = '6'
SELECT CONVERT(VARCHAR(50), @rv , 121)
GO
2 ответа
Порядок выполнения, используя некоторые фактические значения меток времени:
| Event time | Event time | RowVersion |
|---------------------------|-----------------------------|------------|
| Start of trigger | 2017-12-05 10:50:26.8506034 | 28,804,001 |
| End of trigger | 2017-12-05 10:50:26.8506034 | 28,804,002 |
| After insert | 2017-12-05 10:50:26.8662212 | 28,804,002 |
Вы можете превратить rowversion в удобочитаемую форму с помощью:
SELECT CAST(GenerationNumber AS bigint) FROM TestRowVersion --timestamp is an 8-byte (64-bit) integer
Ваша ментальная модель заказа была неправильной.
Таблица:
CREATE TABLE TestRowVersion (
ID varchar(50),
Number varchar(50),
GenerationNumber timestamp
)
Процедура вставки:
ALTER PROCEDURE [dbo].[TestRowVersionProc]
AS
INSERT INTO TestRowversion (ID, Number)
VALUES ('6', '6')
DECLARE @rv bigint
SELECT @rv = CAST(GenerationNumber AS bigint) FROM TestRowversion WHERE ID = '6'
SELECT CAST(SYSDATETIME() AS varchar(50))+' After insert '+CAST(@rv AS varchar(50))
GO
Триггер:
CREATE TRIGGER [dbo].[TestRowversion_AfterInsertUpdate] ON [dbo].[TestRowversion] AFTER INSERT,UPDATE
AS
if @@rowcount = 0 return
set nocount on
DECLARE @rv bigint
SELECT @rv = CAST(GenerationNumber AS bigint) FROM TestRowversion WHERE ID = '6'
SELECT CAST(SYSDATETIME() AS varchar(50))+' Start of trigger '+CAST(@rv AS varchar(50))
DECLARE @Id NVARCHAR(1)
SELECT @Id = ID FROM inserted
UPDATE TestRowversion
SET Number = 'FromTrigger'
WHERE ID = '6'
SELECT @rv = CAST(GenerationNumber AS bigint) FROM TestRowversion WHERE ID = '6'
SELECT CAST(SYSDATETIME() AS varchar(50))+' End of trigger '+CAST(@rv AS varchar(50))
https://docs.microsoft.com/en-us/sql/t-sql/data-types/rowversion-transact-sql
Тип данных rowversion является просто инкрементным числом и не сохраняет дату или время.
У каждой базы данных есть счетчик, который увеличивается на единицу для каждой операции вставки или обновления, выполняемой для таблицы, содержащей столбец версии строки в базе данных. Этот счетчик является версией строки базы данных. Это отслеживает относительное время в базе данных, а не фактическое время, которое может быть связано с часами.
- DATETIME Точность округляется с шагом.000, .003 или.007 секунд