首页 新闻 会员 周边

[SQL SERVER 2008R2]无法对 'cdc' 执行 drop schema,因为对象 'fn_cdc_get_all_changes_ ... ' 正引用它

0
悬赏园豆:200 [已解决问题] 解决于 2016-06-13 08:51

描述:目前有两台主机A和B。在主机A上创建了数据库DB(记为A.DB),并开启了CDC。现将A.DB拷贝至主机B上,搭建为数据库B.DB,并开启了SQL代理。(数据库均为SQL Server 2008r2)

 

现针对B.DB执行如下SQL:

EXEC sys.sp_changedbowner 'sa'; -- 改变用户权限
exec sys.sp_cdc_enable_db; -- 开启数据库 CDC。如果报错,则需要改变用户权限

则出现如下报错:

消息 22906,级别 16,状态 1,过程 sp_cdc_enable_db_internal,第 49 行
因为当前数据库中已存在名为 'cdc' 的数据库用户或名为 'cdc' 的架构,所以无法为变更数据捕获启用数据库 'DB'。变更数据捕获需要独占使用这些对象。请删除或重命名该用户或架构,然后重试相应操作。

而实际上B.DB并未开启CDC。按照提示删除数据库下的cdc架构(删除cdc角色时提示需要先删除架构)

则会出现如下报错:

详细信息如下:

无法对 'cdc' 执行 drop schema,因为对象 'fn_cdc_get_all_changes_ ... ' 正引用它。 (.Net SqlClient Data Provider)

------------------------------
有关帮助信息,请单击: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=10.50.2500&EvtSrc=MSSQLServer&EvtID=3729&LinkId=20476

------------------------------
服务器名称: (local)
错误号: 3729
严重性: 16
状态: 1
行号: 2


------------------------------
程序位置:

   在 Microsoft.SqlServer.Management.Common.ConnectionManager.ExecuteTSql(ExecuteTSqlAction action, Object execObject, DataSet fillDataSet, Boolean catchException)
   在 Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(String sqlCommand, ExecutionTypes executionType)

本人依据相关线索,在网上搜到如下SQL以查询与架构相关的对象:

use DB
go
select obj.type, obj.name
from sys.objects obj join sys.schemas s on(s.schema_id = obj.schema_id)
where s.name = 'cdc'
go

得到部分查询结果如下:

于是想尝试删除sys.objects表中的相关记录:

delete from sys.objects where name = 'fn_cdc_get_all_changes_...'
go

又出现如下报错信息:

消息 259,级别 16,状态 1,第 1 行
不允许对系统目录进行即席更新。

(注:以上SQL操作均位于B.DB)

 

本人最终目的是想开启B.DB的CDC,忘高手解惑。不胜感激~

之由的主页 之由 | 初学一级 | 园豆:6
提问于:2016-06-08 11:02
< >
分享
最佳答案
0

你是怎么拷贝的呢?

收获园豆:200
幻天芒 | 高人七级 |园豆:37175 | 2016-06-09 10:53

在主机A停止SQL server 的服务,然后将A.DB的数据库文件 A.DB.ldf 及 A.DB.mdf 拷贝至主机B。然后利用主机B的 SQL Server Management Studio 附加数据库A.DB为B.DB。

之由 | 园豆:6 (初学一级) | 2016-06-10 10:05

@之由: 附加这种方式,带上了原本数据库的很多信息。考虑下使用备份为bak的方式拷贝呢。

幻天芒 | 园豆:37175 (高人七级) | 2016-06-10 10:43

@幻天芒: 我附加数据库用的是如下SQL

CREATE DATABASE [DB]
    ON (FILENAME = 'D:\A.DB.mdf'), 
    (FILENAME = 'D:\A.DB.LDF') 
    FOR ATTACH;

这样就会和你说的一样,附加原数据库的很多信息。我先按照你说的试试,虽然还没用过备份为bak的方式。

之由 | 园豆:6 (初学一级) | 2016-06-10 10:54

@幻天芒: 我以备份类型为【完整】的方式进行备份,然后再还原数据库,情况依旧,发现和附加数据库似乎没什么区别。cdc架构依然存在,如果手动去删除它,会出现和问题描述中同样情况。

之由 | 园豆:6 (初学一级) | 2016-06-10 11:15

@之由: 在完整备份的设置中,去掉备份数据库架构之类的试试吧。只需要表结构和数据。

幻天芒 | 园豆:37175 (高人七级) | 2016-06-10 13:34

@之由: 实在不行,还可以先关了cdc,复制到新库之后在启用。

幻天芒 | 园豆:37175 (高人七级) | 2016-06-10 13:38

@幻天芒: 好,我再试试。

之由 | 园豆:6 (初学一级) | 2016-06-10 15:42

@幻天芒: 你好,我在备份数据库窗口中,似乎并未找到可以去掉备份数据库架构的选项。

之由 | 园豆:6 (初学一级) | 2016-06-10 15:59

@之由: 用数据库导出工具。可以导出一个带数据的sql文件。

幻天芒 | 园豆:37175 (高人七级) | 2016-06-10 16:38

@幻天芒: 但是这样导出的sql文件会异常庞大,DB备份的.bak文件就有1.5GB

之由 | 园豆:6 (初学一级) | 2016-06-10 18:34

@幻天芒: 或者对于

消息 259,级别 16,状态 1,第 1 行
不允许对系统目录进行即席更新。

这种情况,有没有办法可以做到即席更新,比如对 sys.databases 表。

之由 | 园豆:6 (初学一级) | 2016-06-10 18:49

@之由: 新建一个DB库,然后直接两个库直接导入导出数据。

 

对于消息259这种情况,我没遇到过,不知道如何处理。

幻天芒 | 园豆:37175 (高人七级) | 2016-06-11 08:33

@幻天芒: 虽然没能直接解决问题(开启B.DB的CDC),但通过VS的数据/架构比较复制了去除CDC后同样的数据库(表、函数、存储过程等),只是数据需要另外导入。感谢你提供思路。

之由 | 园豆:6 (初学一级) | 2016-06-13 08:51

@之由: 搞定就好,这个功能应该不常用,网上都没啥资料。

幻天芒 | 园豆:37175 (高人七级) | 2016-06-13 11:06

@幻天芒: 是的,搜国外的也搜不到,唯一搜到相关的就是07年MSDN有人所问删除架构的问题。

之由 | 园豆:6 (初学一级) | 2016-06-13 13:58
其他回答(1)
0

使用drop function和drop procedure删除相关对象

drop function cdc.[fn_cdc_get_all_changes_ ... ]
drop function cdc.[fn_cdc_get_net_changes_ ... ]

drop procedure cdc.sp_ins_lsn_time_mapping

我真的一滴也没有了 | 园豆:202 (菜鸟二级) | 2022-05-31 11:18
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册