我正在 SQL Server 捕获实例上运行以下查询:
DECLARE @from_lsn binary (10), @to_lsn binary (10)
SELECT @from_lsn = sys.fn_cdc_get_min_lsn ( 'dbo_ABC' );
SELECT @from_lsn;
SELECT @to_lsn = sys.fn_cdc_get_max_lsn ();
SELECT *
FROM cdc.fn_cdc_get_all_changes_dbo_ABC(@from_lsn, @to_lsn, 'all');
导致
0x00000000000000000000
值返回 @from_lsn
值,并且 SELECT *
的结果完全为空行:
__$start_lsn | __$seqval | __$操作 | __$update_mask | 我的专栏 |
---|---|---|---|---|
空 | 空 | 空 | 空 | 空 |
注意当查询明显不存在的更改捕获表时,不会发生此行为:
SELECT *
FROM cdc.fn_cdc_get_all_changes_dbo_blahblahblah(@from_lsn, @to_lsn, 'all');
SQL 错误 [208] [S0002]:对象名称“cdc.fn_cdc_get_all_changes_dbo_blahblahblah”无效。
DBA 报告他们无法使用自己的 ID 复制问题。
当为 CDC 设置的表具有查询用户无权访问的角色,或者在设置 CDC 后角色已更改时,会发生这种情况。用户可以保留运行 CDC 函数
fn_cdc_get_all_changes_...
的访问权限,甚至可以查询 cdc
模式中的表。
要检查角色,请运行以下查询:
select
capture_instance,
role_name
from
cdc.change_tables ct
where
capture_instance = 'dbo_ABC'
order by
role_name;
并查找角色名称中的任何差异,这可能表明无法查询捕获实例的原因。
在我们的案例中,该表已在 UAT 数据库中为 CDC 重新注册,并且角色已无意中从
SA_SQLUATRead_CDCRole
更改为 SA_SQLPrdRead_CDCRole
。
使用正确的角色名称重新注册 CDC 表解决了问题,并且用户能够再次查询该表。 DBA 无法复制该问题,因为他们的权限高于 CDC 查询用户的权限。