Числовые столбцы SQL RowVersion для проблемы отслеживания изменений - PullRequest
1 голос
/ 27 июля 2011

У меня есть ситуация, когда я использую столбцы RowVersion и столбцы Binary (8), чтобы отслеживать, была ли изменена строка.

В идеале всякий раз, когда:

RowVersion != Binary(8)

Затем произошли изменения в этой записи.Реальная проблема с этим состоит в том, что я не могу найти хороший метод, чтобы установить два столбца равными.Если я обновлю поле Binary, запрос на обновление увеличивает поле RowVersion для этой записи.Я испортил оптимистическое увеличение поля Binary, и оно почти работает.Ключ в том, что я должен увеличить поле Binary на общее количество записей, на которые повлияет запрос UPDATE.Любая идея о том, как приостановить версию строки или определить, что будет в конце оператора обновления, чтобы использовать значение В операторе обновления?

Для ясности, вот пример того, что будет работать, чтобы сделатьсовпадение двух полей:

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

Ответы [ 2 ]

2 голосов
/ 28 июля 2011

Я не очень уверен, что нет лучшего способа сделать это, но вот вариант:

1.Создайте еще одну таблицу, используя только ПК вашей таблицы и двоичное поле (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 голосов
/ 27 июля 2011

Я бы использовал двоичное поле в отдельной таблице, которая содержит последнее значение версии строки, и поставил бы триггер после таблицы, чтобы синхронизировать их. Затем объедините эти две таблицы и сравните их, если они совпадают.

...