我们在SQL Server 2008 R2(SP 1)上托管了一个SQL Server数据库,并启用了CDC(更改数据捕获)。
由于许可证到期而重新安装SQL Server实例(部署团队忘记安装正确的许可证:())我们将数据库附加到新安装的实例。
但是,并未为所有表启用CDC 当我们尝试通过执行
启用它时sys.sp_cdc_enable_table
我们得到了
未对变更数据捕获启用数据库“DBName”。确保 设置了正确的数据库上下文并重试该操作。至 报告有关为变更数据捕获启用的数据库,查询 sys.databases目录视图中的is_cdc_enabled列。
建议未启用CDC。
因此,我们尝试通过执行
来启用它sys.sp_cdc_enable_db
我们收到以下错误:
消息22906,级别16,状态1,过程sp_cdc_enable_db_internal, 49号线 无法为更改数据启用数据库“DBName” 捕获因为名为“cdc”的数据库用户或名为“cdc”的模式 已存在于当前数据库中。这些对象是必需的 完全由变更数据捕获。删除或重命名用户或架构 并重试该操作。
尝试通过执行
禁用CDCsys.sp_cdc_disable_db
我们再次收到错误相同的错误:
未对变更数据捕获启用数据库“DBName”。确保 设置了正确的数据库上下文并重试该操作。至 报告有关为变更数据捕获启用的数据库,查询 sys.databases目录视图中的is_cdc_enabled列。
我的猜测是,db系统表与导致CDC状态无效的SQL Server系统表之间存在一些不一致。
有没有办法解决这个问题?
任何想法都表示赞赏。
答案 0 :(得分:4)
<强>您好 用于修复Db(删除cdc架构中的所有内容和架构本身) 使用这个:
DECLARE @tableName NVARCHAR(100);
DECLARE myCursor CURSOR FORWARD_ONLY FAST_FORWARD READ_ONLY
FOR
SELECT QUOTENAME(t.name) AS name
FROM sys.tables t
JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE s.name = 'cdc'
OPEN myCursor
FETCH FROM myCursor INTO @TableName
WHILE ( @@Fetch_Status = 0 )
BEGIN
EXEC ( 'drop table cdc.' + @TableName + '; ' );
FETCH NEXT FROM myCursor INTO @TableName
END
CLOSE myCursor
DEALLOCATE myCursor;
go
DECLARE @prName NVARCHAR(100);
DECLARE myCursor2 CURSOR FORWARD_ONLY FAST_FORWARD READ_ONLY
FOR
SELECT QUOTENAME(pr.name) AS name
FROM sys.procedures pr
JOIN sys.schemas s ON pr.schema_id = s.schema_id
WHERE s.name = 'cdc'
OPEN myCursor2
FETCH FROM myCursor2 INTO @prName
WHILE ( @@Fetch_Status = 0 )
BEGIN
EXEC ( 'drop procedure cdc.' + @prName + '; ' );
FETCH NEXT FROM myCursor2 INTO @prName
END
CLOSE myCursor2
DEALLOCATE myCursor2
GO
DECLARE @fnName NVARCHAR(100);
DECLARE myCursor3 CURSOR FORWARD_ONLY FAST_FORWARD READ_ONLY
FOR
SELECT QUOTENAME(fn.name) AS name
FROM sys.objects fn
JOIN sys.schemas s ON fn.schema_id = s.schema_id
WHERE fn.type IN ( 'FN', 'IF', 'TF' )
AND s.name = 'cdc'
OPEN myCursor3
FETCH FROM myCursor3 INTO @fnName
WHILE ( @@Fetch_Status = 0 )
BEGIN
EXEC ( 'drop function cdc.' + @fnName + '; ' );
FETCH NEXT FROM myCursor3 INTO @fnName
END
CLOSE myCursor3
DEALLOCATE myCursor3
go
DECLARE @ruleName NVARCHAR(100);
SELECT @ruleName = DP1.name
FROM sys.database_principals AS DP1
JOIN sys.database_principals AS DP2 ON DP1.owning_principal_id = DP2.principal_id
WHERE DP1.type = 'R'
AND DP2.name = 'cdc';
EXEC ('ALTER AUTHORIZATION ON ROLE::'+@ruleName+' TO dbo; ')
go
DROP SCHEMA [cdc]
GO
DROP USER [cdc]
GO
答案 1 :(得分:0)
我也遇到了处理CDC en / disabling的坏方法。如果我是你,我会尝试删除cdc架构和架构本身的所有内容,并尝试再次在数据库中启用CDC。或者,如果您正在恢复(而不是附加),则有一个KEEP_CDC选项。