1

RowVersion列とBinary(8)列を使用して、行が変更されたかどうかを追跡している状況があります。

理想的にはいつでも:

RowVersion != Binary(8)

その後、その記録に変更がありました。これに関する本当の問題は、2つの列を等しく設定するための適切な方法が見つからないことです。Binaryフィールドを更新すると、更新クエリはそのレコードのRowVersionフィールドをインクリメントします。Binaryフィールドを楽観的にインクリメントすることに混乱しましたが、ほとんど機能します。重要なのは、UPDATEクエリが影響を与えるレコードの総数だけBinaryフィールドをインクリメントする必要があるということです。行バージョンを一時停止する方法、または更新ステートメントの値を使用するために更新ステートメントの最後に何が表示されるかを決定する方法についてのアイデアはありますか?

わかりやすくするために、2つのフィールドを一致させるために機能する例を次に示します。

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

2 に答える 2

2

最後のrowversion値を保持する別のテーブルでバイナリフィールドを使用し、それらを同期するためにテーブルにafterトリガーを配置します。次に、これら2つのテーブルを結合し、同じであるかどうかを比較します。

于 2011-07-27T19:23:10.037 に答える
2

これを行うためのより良い方法があるかどうかはよくわかりませんが、次のオプションがあります。

1.テーブルのPKとbinary(8)フィールドのみを使用して別のテーブルを作成します。

2.行バージョンをテーブルの行から2番目のテーブルの関連する行にコピーします(必要な時点で)。

3.次に、後でこれら2つのフィールド(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を使用して外部キー制約を削除することで、削除を確認できます。

于 2011-07-27T20:24:00.693 に答える