如何在 SQL Server 中将时间戳/行版本转换为日期和时间?

Hen*_*sen 1 sql-server timestamp

如何在 SQL Server 中将时间戳/行版本转换为日期和时间?

我有几个表,我想在其中跟踪上次更新,列名称如ModifiedAt, UpdatedAt, UpdatedDate

如果它们使用 Rowversion 数据类型或 Timestamp 数据类型,这可能吗?

CREATE TABLE dbo.Customer (
    CustomerID BIGINT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
    CustomerName NVARCHAR(200) NOT NULL ,
    CreatedAt DATETIME2 NOT NULL CONSTRAINT df_Customer_CreatedAt DEFAULT GETUTCDATE(),
    UpdatedAt ROWVERSION NOT NULL /* does this work ? */
) 
Run Code Online (Sandbox Code Playgroud)

Hen*_*sen 5

无法TimeStamp 列转换为日期和时间格式。Microsoft 已将 TimeStamp 数据类型重命名为 RowVersion 以避免混淆。

timestamp/rowversion 数据类型实际上只是一个数据库事务 ID,它也可以存储在 Binary(8) 数据类型的列中。

这里有一个解决方法来实现 ModifiedAt、UpdatedDate 列类型。这会将 RowVersion 列转换(或“转换”)为 SmallDateTime 数据类型,可以根据您的需要进行格式化。

但你需要做一些工作;

1. 创建一个包含三列的表“UpdateTimeStamp”

(CreatedDate Smalldatetime, NewRowVersion, OldRowVersion) 像这样:

Create Table dbo.UpdateTimeStamp(
    OldRowVersion binary(8) not null, 
    CreatedDate SmallDateTime not null constraint DF_UpdateTimeStamp_CreatedDate Default getdate(),
    NewRowVersion ROWVERSION not null CONSTRAINT PKUpdateTimeStamp PRIMARY KEY CLUSTERED
)
Run Code Online (Sandbox Code Playgroud)

手动插入第一行

Insert into dbo.UpdateTimeStamp(OldRowVersion, CreatedDate) 
VALUES (0x0000000000000000, '2000-01-01')
Run Code Online (Sandbox Code Playgroud)

2. 创建SQL代理作业

创建一个标准 SQL 代理作业,每隔一分钟在表中插入一行。

让步骤 1 运行此代码:

Insert into dbo.UpdateTimeStamp(OldRowVersion) 
SELECT TOP (1) NewRowVersion 
FROM dbo.UpdateTimeStamp 
ORDER BY NewRowVersion DESC
Run Code Online (Sandbox Code Playgroud)

将计划设置为每 1 分钟运行一次。

3、查询数据

您需要将包含 UpdateTimeStamp 表的联接的查询写入到带有 Between join 子句的表中,如下所示:

SELECT top 10000 mt.*, uts.CreatedDate AS ModifiedDate 
FROM dim.MyTable MT 
LEFT JOIN dbo.UpdateTimeStamp uts 
    ON MT.DT1RowVersion > OldRowVersion AND MT.DT1RowVersion <= NewRowVersion
ORDER BY uts.CreatedDate
Run Code Online (Sandbox Code Playgroud)

警告,但是...

1)Microsoft SQL Server不太擅长“日期范围连接”子句,因此如果您不需要分钟分辨率,但10分钟精度可以接受,那么您可以通过降低SQL代理的频率来提高查询速度工作间隔为 10 分钟。

2) 这仅适用于 SQL 代理作业运行的时间段,因为追溯创建 dbo.UpdateTimeStamp 表并不容易。除非您有一个具有 RowVersion/TimeStamp 数据类型的旧表,并且该表也永远不会看到更新,并且该表具有 CreatedDate 列。并且该表必须位于同一服务器上的同一数据库中。

额外功能

RowVersion 列已添加到数据仓库中已有的许多表中,因为我将其用作将数据加载到数据集市的水印。因此,当我需要调查我们的事实和维度何时出现问题时,我可以将此功能作为调试选项。此外,我不需要触发器,如果​​编码不正确,触发器可能会出现性能问题和/或稳定性问题。