Попытка понять некоторые функции отслеживания изменений SQL Server

Я работаю над SQL Server 2016 SP1 с функцией отслеживания изменений, и у меня есть к вам вопрос.

У меня есть база данных, в которой включено отслеживание изменений. Эта база данных содержит таблицу Table, в которой активировано «отслеживание изменений», но не включена опция «отслеживание обновленных столбцов».

Например, на Table у меня есть только один столбец с именем Id типа "uniqueidentifier", который является моим ПК.

При запуске моя текущая версия отслеживания изменений равна 0.

Я получил это с:

SELECT CHANGE_TRACKING_CURRENT_VERSION();

Я добавил новую строку в Table:

INSERT INTO dbo.[Table] (Id) 
VALUES ('C99F9E2A-1974-47CE-A406-481076F53BBD');

Теперь моя текущая версия отслеживания изменений теперь 1.

С помощью этого запроса я могу увидеть свой элемент в системе отслеживания изменений:

SELECT * 
FROM CHANGETABLE (CHANGES dbo.[Table], 0) CT;

Результат:

результат 1

Теперь я удаляю свою строку следующим образом:

DELETE FROM dbo.[Table] 
WHERE Id = 'C99F9E2A-1974-47CE-A406-481076F53BBD';

Текущая версия отслеживания изменений теперь 2.

Я вставляю его снова с тем же запросом, что и предыдущий.

Текущая версия отслеживания изменений теперь 3.

С этим запросом я получил такой результат:

SELECT * 
FROM CHANGETABLE (CHANGES dbo.[Table], 1) CT;

введите здесь описание изображения

Теперь мой вопрос, почему я получил «U» в SYS_CHANGE_OPERATION?

Почему бы не «я» вызвать 1 ‹ SYS_CHANGE_CREATION_VERSION, что равно 3?

Спасибо за вашу помощь !


person rognar    schedule 07.09.2018    source источник


Ответы (2)


В качестве дополнительной мотивации цель функций отслеживания изменений состоит в том, чтобы дать вам возможность увидеть, что изменилось с момента последней проверки, и позволить вам собрать и применить эти изменения к какой-либо другой таблице или внешней системе. .

Если вы посмотрите на изменения с момента сразу после удаления, вы увидите операцию как I. Но если вы посмотрите на изменение с момента удаления, вы «пропустите» удаление. Но отслеживание изменений не запоминает, какими были неключевые значения до удаления. Таким образом, строка сообщается как обновленная.

EG

ALTER DATABASE current  
SET CHANGE_TRACKING = ON  
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON)  
go
drop table if exists ct

create table ct(id uniqueidentifier primary key)

ALTER TABLE ct
ENABLE CHANGE_TRACKING  
WITH (TRACK_COLUMNS_UPDATED = ON) 

declare @beforeInsert bigint = (SELECT CHANGE_TRACKING_CURRENT_VERSION());
INSERT INTO dbo.ct (Id) VALUES ('C99F9E2A-1974-47CE-A406-481076F53BBD');
declare @afterInsert bigint = (SELECT CHANGE_TRACKING_CURRENT_VERSION());
DELETE FROM dbo.ct WHERE Id = 'C99F9E2A-1974-47CE-A406-481076F53BBD';
declare @afterDelete bigint = (SELECT CHANGE_TRACKING_CURRENT_VERSION());
INSERT INTO dbo.ct (Id) VALUES ('C99F9E2A-1974-47CE-A406-481076F53BBD');


SELECT 'from before insert to current',id, sys_change_operation FROM CHANGETABLE (CHANGES dbo.ct, @beforeInsert) CT
union all
SELECT 'from after insert to current',id, sys_change_operation FROM CHANGETABLE (CHANGES dbo.ct, @afterInsert) CT
union all
SELECT 'from after delete to current',id, sys_change_operation FROM CHANGETABLE (CHANGES dbo.ct, @afterDelete) CT

выходы

                              id                                   sys_change_operation
----------------------------- ------------------------------------ --------------------
from before insert to current C99F9E2A-1974-47CE-A406-481076F53BBD I
from after insert to current  C99F9E2A-1974-47CE-A406-481076F53BBD U
from after delete to current  C99F9E2A-1974-47CE-A406-481076F53BBD I
person David Browne - Microsoft    schedule 07.09.2018
comment
о, конечно, приведите хороший пример :-). - person Hannah Vernon; 07.09.2018

Из Microsoft Docs CHANGETABLE

Если вы удалите строку, а затем вставите строку со старым первичным ключом, изменение будет рассматриваться как обновление всех столбцов в строке.

Предположительно, id является первичным ключом рассматриваемой таблицы.

Кроме того, не используйте id в качестве имени столбца, используйте TableID... поэтому, если имя таблицы Users, то первичный ключ (при использовании суррогатного ключа) должен быть UserID. Использование id в качестве имени столбца первичного ключа приводит к значительной путанице и делает ваш код подверженным ошибкам. Подробнее об этом читайте в этом ответе.

person Hannah Vernon    schedule 07.09.2018
comment
Это именно то, что я только что подумал в своей голове. Хотя я не уверен, что полностью согласен с последним абзацем вашего ответа. Я не возражаю против имен PK ID с именами FK UserId. - person Tanner; 07.09.2018
comment
FWIW, я часто вижу Id, где задействован ORM, поскольку он позволяет OO-коду работать с сущностями в целом. - person David Browne - Microsoft; 07.09.2018
comment
Также Id лучше воспроизводит подтипы моделирования. Таким образом, вы не закончите как Adventureworks, где Sales.SalesPerson имеет PK BusinessEntityId - person David Browne - Microsoft; 07.09.2018