用于更改跟踪问题的 SQL RowVersion 编号列

Posted

技术标签:

【中文标题】用于更改跟踪问题的 SQL RowVersion 编号列【英文标题】:SQL RowVersion number columns for change tracking problem 【发布时间】:2011-07-27 15:47:52 【问题描述】:

我有一种情况,我使用 RowVersion 列和 Binary(8) 列来跟踪行是否已更改。

理想情况下:

RowVersion != Binary(8)

然后该记录发生了变化。真正的问题是我找不到将两列设置为相等的好方法。如果我更新 Binary 字段,则更新查询会增加该记录的 RowVersion 字段。我已经搞砸了乐观地增加 Binary 字段,它几乎可以工作。关键是我必须将 Binary 字段增加 UPDATE 查询将影响的记录总数。关于如何暂停 rowversion 或确定在更新语句结束时使用更新语句中的值的任何想法?

为清楚起见,以下是使两个字段匹配的示例:

    UPDATE [table] SET BinaryField = MyRowVersion + 
(SELECT COUNT(*) FROM [table] WHERE (MyRowVersion != BinaryField)) 
WHERE (MyRowVersion != BinaryField)

【问题讨论】:

为什么要用行数更新二进制列?然后期望它与 rowversion 列同步? 可能有点不清楚。如果要将二进制列设置为与行版本相同的值,则必须添加受影响记录的计数以使它们相等。 rowversion 是数据库唯一的:与行数完全无关。你说的话有参考吗? MSDN 说msdn.microsoft.com/en-us/library/ms182776.aspx“是一种在数据库中公开自动生成的唯一二进制数的数据类型。”和“rowversion 数据类型只是一个递增的数字” 那么,除了 rowversion 字段之外,您还希望设置另一个字段来存储(现在或在某个时间点)与 rowversion 字段相同的值吗?那么,当您稍后比较这两个时,您会知道该行是否有更新? 我正在尝试简单地跟踪更改的记录。如果记录已更改,则两列将不匹配。如果它们没有被改变,那么这两列将是相等的。查询完所有更改后,我需要使列相等,以便找出接下来的更改。 【参考方案1】:

我不太确定没有更好的方法可以做到这一点,但这里有一个选择:

1.创建另一个表,仅包含表的 PK 和 binary(8) 字段。

2.将行版本从表的行复制到第二个表的相关行(在您想要的时间点)。

3.然后,当你以后可以比较这两个字段时(rowversion,binary(8))。

--- 1 ---
CREATE TABLE MyTest 
( myKey INT PRIMARY KEY
, myData INT
, RV rowversion
) ;

CREATE TABLE MyTestCheck
( myKey INT PRIMARY KEY
, RVcheck binary(8)
, FOREIGN KEY (myKey) REFERENCES MyTest(myKey)
) ;

--- 2 ---
UPDATE MyTestCheck 
SET RVcheck = RV
FROM MyTest 
WHERE MyTest.myKey = MyTestCheck.myKey ;

INSERT INTO MyTestCheck
  SELECT myKey, RV
  FROM MyTest
  WHERE myKey NOT IN
    ( SELECT myKey
      FROM MyTestCheck
    ) ;

--- 3 ---
SELECT m.*, m2.RVcheck 
FROM MyTest AS m
  LEFT JOIN MyTestCheck AS m2
    ON m2.myKey = m.myKey 
WHERE m2.RVcheck <> m.RV          --- updates since last time procedure2 run
   OR m2.RVcheck IS NULL ;        --- inserts since  ...

您可以检查删除,使用 FULL JOIN 并删除外键约束。

【讨论】:

【参考方案2】:

我会在单独的表上使用二进制字段来保存最后一个 rowversion 值,并在表上放置一个后触发器来同步这些值。然后加入这两个表并比较它们是否相同。

【讨论】:

我想到了。不过,我确实需要在多个表上实现这一点,这会带来问题(除非为每个表创建一个同步表)。

以上是关于用于更改跟踪问题的 SQL RowVersion 编号列的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server RowVersion/时间戳 - 比较

Microsoft SQL Server Management Studio 说 RowVersion 是无效类型

SQL MIN_ACTIVE_ROWVERSION() 值长时间不变

探究SQL SERVER 更改跟踪

探究SQL SERVER 更改跟踪

是否可以使用实体框架将 SQL Server 的 rowversion 类型映射到比 byte[] 更友好的东西?