0

I've just started using T-SQL's RowVersion and I've noticed something very interesting. I created a Proc to update a table with a RowVersion column and at the end of this proc I print out a humanreadable date representation of RowVersion. I also added a Trigger which updates data in the table and prints out RowVersion before and after. It's given some interesting results...

From Insert Proc after data is inserted = 1900-01-01 05:43:13.373

From start of Trigger before we change any data = 1900-01-01 05:43:13.377

From end of trigger after data has changed = 1900-01-01 05:43:13.377

The start of the trigger value for the RowVersion column has changed from the end of the proc value for the RowVersion Column despite the fact we have not augmented any data yet. It's also the same as the end of the Trigger. Why is this? Is it something to do with the sequencing of SQL statement execution? Any help understanding this would be appreciated. The proc and trigger are listed below:

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
4

2 回答 2

0

https://docs.microsoft.com/en-us/sql/t-sql/data-types/rowversion-transact-sql

  1. rowversion 数据类型只是一个递增的数字,不保留日期或时间。

  2. 每个数据库都有一个计数器,对于在数据库中包含 rowversion 列的表执行的每个插入或更新操作,该计数器都会递增。此计数器是数据库行版本。这跟踪数据库中的相对时间,而不是可以与时钟关联的实际时间。

  3. DATETIME 精度四舍五入到 0.000、0.003 或 0.007 秒的增量
于 2017-12-05T15:37:59.427 回答
0

执行顺序是,使用一些实际的时间戳值:

| 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))
于 2017-12-05T16:06:11.883 回答