询问者
SQL Server的复制设置中已经禁用复制外键约束,但一段时间后在订阅数据库表上还是看到外键约束,这算Bug吗?

问题
全部回复
-
I understand. There is indeed a 'forced to be used in replication' option in fkeys settings.
- 已编辑 Mike Zhang (mz24cn) 2014年2月28日 1:54
-
That's way you have to use 'not for replication' when create fkey in replicated table.
- 已标记为答案 Michelle GeModerator 2014年3月6日 8:42
- 取消答案标记 Mike Zhang (mz24cn) 2014年3月7日 10:18
- 已建议为答案 i6first 2014年3月11日 0:59
- 取消建议作为答案 Mike Zhang (mz24cn) 2016年2月16日 9:44
-
-
这个问题是2年前问的,但是没有解决问题。几个回复的答案都没法说明该如何操作。几年了一直被这个问题困扰着。请问还有人能给个明确答案说明如何阻止订阅数据库表上出现外键吗?发布表中创建外键约束时指定“not for replication”,请问您说的这个操作是如何操作?您能说明确吗?
我是真想提Bug了。不过提了Bug估计也没用。我还有个IE Javascript CROS的Bug也挂了几年了,也没个说法。
微软有人能看到吗?
- 已编辑 Mike Zhang (mz24cn) 2016年2月16日 9:44
-
NOT FOR REPLICATION选项作用于订阅服务器,如果你的外键约束是直接在订阅服务器上的,则需要确保有这个选项,类似于
ALTER TABLE xx ADD FOREIGN KEY( fk_column ) REFERENCES fk_tb ( key_column ) NOT FOR REPLICATION
如果你的外键约束是在发布服务器上的,那么分几种情况:
1. 如果约束是在配置同步前建的
1-1 如果建同步时指定不复制外键约束,那么外键约束不会复制过去,不会有问题
1-2 如果复制外键约束,那么需要确保外键是能 NOT FOR REPLICATION选项创建的,否则会有问题
2. 如果外键是配置同步后之后创建的
2-1 如果建外键约束有指定 NOT FOR REPLICATION选项,那么没有问题
2-2 如果没有指定 NOT FOR REPLICATION选项
2-2-1 如果发布项目的 @schema_option 选项有指定 0x20000,那么没有问题
2-2-2 如果未指定,则应该会有问题
@schema_option 为 sp_addarticle 和 sp_changearticle 的参数,0x20000 这个值在界面中我没有看到有对应的配置项,应该只能用脚本来操作了 ( 已经配置的同步的该值可以在对应的发布数据库中查询 sysarticles 表)
-
邹建,rmiao:
谢谢回复。我截图你们看下是什么情况。这是发布数据库的表的外键情况。强制用于复制是选“否”的。
下图是订阅数据库对应表的外键的情况:
这里出现了16进制编码名称的外键名,对应的还是第一张图里面的外键。就是这里的外键容易在复制同步时出现问题,因为外键约束导致数据删除出现问题,进而导致同步不能继续。如果把订阅数据库的表的所有外键都删除,就正常了。
可以用存储过程把订阅数据库的所有外键都删除,但是一段时间后,这些16进制编码名称的外键又会出现,这是怎么回事呢?
发布数据库是2008R2版本(10.50.1600.1),订阅数据库是2005版本(9.00.1399)。订阅数据库有多个,其中也有2008的版本。
邹建所说的“外键约束”,你说的就是“键”分支中的FK开头的外键吗?因为微软SQLServer管理器“键”分支下面还有个“约束”分支,里面的项目跟外键其实没关系(我怕概念理解上有歧义)。
我的表的这些外键,是在创建复制之前就建好的,建外键时,我没有看到你和rmiao所说的“NOT FOR REPLICATION”选项,只有“强制用于复制”选项,而且如你所见,这个是选否的。
创建复制的属性我也截图下:
好了,我只找到这些地方可以控制外键复制的问题,我设置有什么问题吗?该怎么办?
-
你的意思明确的说,就是GUI界面上是没有这个操作选项的,只能在发布和订阅数据库两边同时运行Alter table ... not for replication这个SQL才行,对不对?
要想想多个订阅数据库,以及数据库里几十上百的表,每个订阅库的每个表都要这样操作,这个工作量多大,还要写存储过做这个事情吗?
不这样操作就会导致同步在运行一段时间后几乎是必然的会失败。请问这还不算Bug吗?
简化一下我前面说的,具体的你再仔细看下:
如果设置 schema option, 那么不需要alter table not for replication,这个在编写订阅外键约束的时候会自动加上,但这个选项界面上是没有的,需要通过 sp_addarticle 或 sp_changearticle 设置(也就是用脚本的方式添加或者个性发布项目)
如果你不用脚本的方式,那么在配置发布的时候,可以选择不复制外键,但在配置好发布之后所添加的外键,需要确保有使用 not for replication 选项