我的表中有一个名为RowVersion的LastChanged列。
ID = LastChanged _ Foo _
我正在开发一些与同步相关的功能。我将从表中选择一个分钟到最大的RowVersion之间的所有记录。初始同步不会有Min版本,所以我将包含所有行(直到MIN_ACTIVE_ROWVERSION() )。
随后的同步将有一个最小的RowVersion -通常是来自上一次同步的MIN_ACTIVE_ROWVERSION()。
像这样选择Min和Max RowVersion之间的行很容易。不过,我还想确定哪些行是Inserts,哪些行是Updates。对我来说,最简单的方法是添加另一列:
ID = LastChanged (RowVersion) \ CreationRowVersion (二进制(8))
对于CreationRowVersion,其思想是捕获插入时的RowVersion值。这样,该行的值就永远不会更改。因此,在最初插入行时,我想将CreationRowVersion默认为与RowVersion相同的值。
这样,我就可以确定在上次同步(即min和max RowVersions之间)之后创建了哪些行,哪些行已经更新--因为对于已创建的行,我可以查看属于min和max行版本范围内的CreationRowVersion行。对于更新的行,我可以查看在min和max行版本范围内具有LastChanged的行,但如果行的CreationRowVersion也位于min和max RowVersions之间,则也可以将行排除为“更新”,因为我当时知道它们实际上已经包含为插入。
所以现在背景已经消失了,这就引出了我问题的症结所在。在插入时将CreationRowVersion默认为RowVersion的最有效方法是什么?这是通过列的默认约束来完成的,还是必须通过触发器来完成?我希望这个列是一个二进制(8),因为它与RowVersion的数据类型匹配。
谢谢
发布于 2017-09-21 18:43:04
尝试使用ROWVERSION()函数作为CreationRowVersion BINARY(8)列的默认值。
CREATE TABLE dbo.RowVerTest (
ID INT IDENTITY,
LastChanged ROWVERSION,
CreationRowVersion BINARY(8)
CONSTRAINT DF_RowVerTest_CreationRowVersion DEFAULT(MIN_ACTIVE_ROWVERSION()),
Foo VARCHAR(256)
)
GO
INSERT INTO dbo.RowVerTest (Foo) VALUES ('Hello');
GO
--[LastChanged] and [CreationRowVersion] should be equal.
SELECT * FROM dbo.RowVerTest;
GO
UPDATE dbo.RowVerTest SET Foo = 'World' WHERE ID = 1;
GO
--[LastChanged] should be incremented, while [CreationRowVersion]
--should retain its original value from the insert.
SELECT * FROM dbo.RowVerTest;
GO注意:在我的测试中,只有在每次插入一个行时,上面的内容才有效。下面的场景代码似乎不适用于您的用例:
--Insert multiple records with a single INSERT statement.
INSERT INTO dbo.RowVerTest (Foo)
SELECT TOP(5) name FROM sys.objects;
--All the new rows have the same value for [CreationRowVersion] :{
SELECT * FROM dbo.RowVerTest;发布于 2017-09-21 18:08:31
有一个关于在默认语句中引用列的现有问题。您不能这样做,但是还有其他建议要考虑,包括一个“后插入”触发器。
您可能想看看RowVersion与性能上的这个问题。
https://stackoverflow.com/questions/46345047
复制相似问题