Инкремент 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

  1. Тип данных rowversion является просто инкрементным числом и не сохраняет дату или время.

  2. У каждой базы данных есть счетчик, который увеличивается на единицу для каждой операции вставки или обновления, выполняемой для таблицы, содержащей столбец версии строки в базе данных. Этот счетчик является версией строки базы данных. Это отслеживает относительное время в базе данных, а не фактическое время, которое может быть связано с часами.

  3. DATETIME Точность округляется с шагом.000, .003 или.007 секунд
Другие вопросы по тегам