[英]Creating a trigger to count how many times a piece of data has been changed SQL
[英]SQL RowVersion incrementing before data has been augmented in Trigger
我剛剛開始使用T-SQL的RowVersion,並且發現了一些非常有趣的東西。 我創建了一個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列的觸發值的起始位置已與RowVersion列的proc值的末尾有所不同。 它也與觸發器的末尾相同。 為什么是這樣? 這與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
https://docs.microsoft.com/zh-cn/sql/t-sql/data-types/rowversion-transact-sql
rowversion數據類型只是一個遞增數字,並不保留日期或時間。
每個數據庫都有一個計數器,該計數器針對在數據庫中包含rowversion列的表上執行的每個插入或更新操作遞增。 此計數器是數據庫行版本。 這將跟蹤數據庫中的相對時間,而不是可與時鍾關聯的實際時間。
執行的順序是,使用一些實際的時間戳值:
| 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 |
您可以使用以下方法將行版本轉換為易於閱讀的形式:
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))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.