我刚刚开始使用T-SQL的RowVersion,我注意到了一些非常有趣的东西。我创建了一个Proc以使用RowVersion列更新表,并在此proc的末尾打印出RowVersion的可读日期表示。我还添加了一个Trigger,它更新表中的数据并打印出RowVersion之前和之后。它给出了一些有趣的结果......
插入数据后从插入过程= 1900-01-01 05:43:13.373
从触发开始之前我们更改任何数据= 1900-01-01 05:43:13.377
数据发生变化后触发结束= 1900-01-01 05:43:13.377
RowVersion列的触发器值的开始已从RowVersion列的proc值的末尾更改,尽管我们还没有扩充任何数据。它也与Trigger的结尾相同。为什么是这样?它与SQL语句执行的顺序有关吗?任何帮助理解这一点将不胜感激。 proc和触发器列在下面:
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
答案 0 :(得分:0)
https://docs.microsoft.com/en-us/sql/t-sql/data-types/rowversion-transact-sql
rowversion数据类型只是一个递增的数字,不会保留日期或时间。
每个数据库都有一个计数器,该计数器针对在数据库中包含rowversion列的表上执行的每个插入或更新操作递增。此计数器是数据库rowversion。这会跟踪数据库中的相对时间,而不是可以与时钟关联的实际时间。
答案 1 :(得分: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))