mag*_*tic 2 sql-server change-data-capture
使用 SQL Server 2012,我有一个分层表布局 (TPT)。所有表都“继承”自同一个基表 ( dbo.DataObjects
)。所有表都通过 CDC 启用历史记录跟踪。
我正在尝试编写一个通用函数,该函数返回给定类型的 CDC 历史信息,包括所有基表中的相关信息。
假设我的类型是直接继承自 的User
表,我的查询应该如下所示:dbo.Users
dbo.DataObjects
DECLARE @Begin_LSN binary(10),@End_LSN binary(10)
SELECT @Begin_LSN = sys.fn_cdc_get_min_lsn('dbo_Users')
SELECT @End_LSN = sys.fn_cdc_get_max_lsn()
SELECT * FROM cdc.fn_cdc_get_all_changes_dbo_DataObjects(@Begin_LSN, @End_LSN,'ALL') AS a
JOIN cdc.fn_cdc_get_all_changes_dbo_Users(@Begin_LSN, @End_LSN,'ALL') AS b
ON a.__$start_lsn = b.__$start_lsn
WHERE ID = 10;
Run Code Online (Sandbox Code Playgroud)
这将为我提供 ID 为 10 的用户的完整历史记录,包括基表中的列。
现在我想动态构建这种查询。
我的问题之一是 cdc 检索历史信息的函数包括捕获实例的名称:
cdc.fn_cdc_get_all_changes_<capture_instance>
Run Code Online (Sandbox Code Playgroud)
我还需要第二行中的捕获实例的名称来获取最小 lsn:
sys.fn_cdc_get_min_lsn('<capture_instance>')
Run Code Online (Sandbox Code Playgroud)
当我为表启用 CDC 时,捕获实例名称会自动创建,或者手动传递。如果我不想自己跟踪捕获实例名称,有没有办法检索给定表的捕获实例的名称?
我知道每个表可以有多个捕获实例(我认为最多 2 个),但我可能总是每个表只使用一个。
PS:我也知道捕获实例名称通常是以 的方式构建的<schema>_<table>
,但依赖这种假设似乎有点冒险。未来版本的命名约定可能会发生变化,或者有人可以提供手动捕获实例名称/更改名称。
输入(希望是存储过程参数):
DECLARE @table1 NVARCHAR(513) = N'dbo.Users',
@table2 NVARCHAR(513) = N'dbo.DataObjects',
@ID INT = 10;
Run Code Online (Sandbox Code Playgroud)
代码:
DECLARE @InstanceName1 NVARCHAR(513),
@InstanceName2 NVARCHAR(513),
@Begin_LSN BINARY(10),
@End_LSN BINARY(10);
SELECT @InstanceName1 = c.capture_instance
FROM cdc.change_tables AS c
INNER JOIN sys.tables AS t
ON c.[source_object_id] = t.[object_id]
INNER JOIN sys.schemas AS s
ON t.[schema_id] = s.[schema_id]
WHERE t.name = PARSENAME(@table1,1)
AND s.name = PARSENAME(@table1,2);
SELECT @InstanceName2 = c.capture_instance
FROM cdc.change_tables AS c
INNER JOIN sys.tables AS t
ON c.[source_object_id] = t.[object_id]
INNER JOIN sys.schemas AS s
ON t.[schema_id] = s.[schema_id]
WHERE t.name = PARSENAME(@table2,1)
AND s.name = PARSENAME(@table2,2);
SELECT @Begin_LSN = sys.fn_cdc_get_min_lsn(@InstanceName1),
@End_LSN = sys.fn_cdc_get_max_lsn();
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'SELECT *
FROM cdc.fn_cdc_get_all_changes_' + @InstanceName2
+ '(@b, @l, ''ALL'') AS a
INNER JOIN cdc.fn_cdc_get_all_changes_' + @InstanceName1
+ '(@b, @l, ''ALL'') AS b
ON a.__$start_lsn = b.__$start_lsn
WHERE a.ID = @ID;';
------^ guessing here
EXEC sp_executesql @sql,
N'@b BINARY(10), @l BINARY(10), @ID INT',
@Begin_LSN, @End_LSN, @ID;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
9331 次 |
最近记录: |