试图了解一些SQL Server更改跟踪功能

时间:2018-09-07 14:24:31

标签: sql-server change-tracking

我正在使用具有变更跟踪功能的SQL Server 2016 SP1,但有一个问题要问您。

我有一个启用了更改跟踪的数据库。该数据库包含一个表Vue.use(VueEcho, { broadcaster: 'pusher', key: 'xxxxxxxxxxxxxx', cluster: 'eu', authEndpoint: 'http://localhost/api.easycargo.ro/public/broadcasting/auth', auth: { headers: { 'x-session': this.auth.token } } }); ,该表已激活“更改跟踪”,但未激活“更新跟踪列”选项。

例如,在Table上,我只有一个名为Table的列,其类型为“ uniqueidentifier”,这是我的PK。

开始时,我的更改跟踪当前版本为0。

我用:

Id

我向SELECT CHANGE_TRACKING_CURRENT_VERSION(); 添加了新行:

Table

现在,我的更改跟踪当前版本为1。

通过此请求,我可以在变更跟踪系统中看到我的元素:

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

结果是:

result 1

现在,我用以下命令删除行:

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

更改跟踪当前版本为2。

我以与先前相同的请求再次插入。

更改跟踪当前版本为3。

有了这个请求,我得到了这个结果:

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

enter image description here

现在是我的问题,为什么我在SYS_CHANGE_OPERATION中得到“ U”?

“ I”为什么不引起1

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

来自Microsoft Docs CHANGETABLE

  

如果删除一行,然后插入具有旧主键的行,则该更改将视为该行中所有列的更新。

大概id是所讨论表的主键。

此外,请勿使用id作为列名,而使用TableID ...因此,如果表名是Users,则为主键(如果使用代理密钥)应为UserID。使用id作为主键列的名称会造成很大的混乱,并使代码易于出错。看看this的答案,了解有关的详细信息。

答案 1 :(得分:3)

添加一些动机,更改跟踪功能的目的是使您能够查看自上次检查以来发生了什么变化,使您可以收获这些变化并将其应用于其他表或外部系统。

如果您查看删除后 之后的更改,您将看到操作为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