复制支持对已发布对象进行多种架构更改。 对 Microsoft SQL Server 发布服务器中相应的发布对象进行下列任何一种架构更改时,默认会将该更改传播到所有 SQL Server 订阅服务器:
ALTER TABLE
ALTER TABLE SET如果启用了架构更改复制功能,并且拓扑中包含 SQL Server 2005 (9.x) 或 SQL Server Compact 3.5 订阅方,则不应使用 LOCK ESCALATION。
ALTER VIEW
ALTER PROCEDURE
ALTER FUNCTION
ALTER TRIGGER
ALTER TRIGGER 只能用于数据操作语言 [DML] 触发器,因为无法复制数据定义语言 [DDL] 触发器。
重要
对表进行架构更改时必须使用 Transact-SQL 或 SQL Server 管理对象 (SMO)。 在 SQL Server Management Studio 中进行架构更改时,Management Studio 将尝试删除并重新创建表。 因为无法删除已发布的对象,所以架构更改失败。
对于事务复制和合并复制,在分发代理或合并代理运行时,架构变更会以增量方式传播。 在快照复制中,当在订阅服务器上应用新快照时,架构更改会被传播。 在快照复制中,每次同步时,都会向订阅服务器发送架构的新副本。 因此,每次同步时都自动传播对以前发布的对象的所有架构更改(而不只是上面列出的那些)。
有关在发布中添加和删除项目的信息,请参阅向现有发布添加项目和从中删除项目。
复制架构变更
默认情况下会复制上面列出的架构更改。 有关禁止复制架构更改的信息,请参阅 Replicate Schema Changes。
架构更改的注意事项
复制架构更改时,请牢记下列注意事项:
一般注意事项
架构更改需遵守 Transact-SQL 规定的所有限制。 例如, ALTER TABLE 不允许更改主键列。
仅对初始快照执行数据类型映射。 架构更改不会映射到以前版本的数据类型。 例如,如果在 SQL Server 2012 (11.x) 中使用语句
ALTER TABLE ADD datetime2 column,则对于 SQL Server 2005 (9.x) 订阅服务器,数据类型不会被转换为 nvarchar。 在某些情况下,架构更改在发布服务器上受到阻止。如果发布被设置为允许传播架构更改,则不论为发布中的项目设置的相关架构选项是什么,都会传播架构更改。 例如,如果你选择不复制某个表项目的外键约束,但随后发出ALTER TABLE命令,在发布服务器上的该表中添加外键,则该外键也会添加到订阅服务器上的该表中。 若要防止这种情况,请在发出 ALTER TABLE 命令之前禁用架构更改的传播。
架构更改只应在发布服务器中进行,不应在订阅服务器中(包括重新发布订阅服务器)上进行。 合并复制会阻止在订阅服务器上进行架构变更。 事务复制虽然不禁止更改,但更改可能会导致复制失败。
传播到重新发布订阅者的更改默认也会传播到其订阅者。
如果架构更改引用存在于发布服务器中而不存在于订阅服务器中的对象或约束,则架构更改将在发布服务器中成功,但在订阅服务器上失败。
添加外键时引用的订阅服务器中的所有对象必须与发布服务器中的相应对象具有相同的名称和所有者。
不会复制显式添加、删除或更改索引,并且涉及显式索引的任何更改都需要在每个副本集上单独运行。 支持为约束(如主键约束)隐式创建的索引。
不支持更改或删除由复制管理的标识列。 有关自动管理标识列的详细信息,请参阅复制标识列。
不支持包含不确定性函数的架构更改,因为它们可能会导致发布服务器和订阅服务器中的数据不同(称为无法收敛)。 例如,如果在发布服务器发出以下命令:
ALTER TABLE SalesOrderDetail ADD OrderDate DATETIME DEFAULT GETDATE(),则将此命令复制到订阅服务器并执行时,会得到不同的值。 有关不确定性函数的详细信息,请参阅 Deterministic and Nondeterministic Functions。建议显式命名约束。 如果不显式命名约束,SQL Server 将为约束生成名称,并且这些名称在发布服务器和每个订阅服务器中都不同。 这在复制架构更改时会引发问题。 例如,如果在发布服务器中删除一列并删除了一个相关约束,则复制将尝试在订阅服务器中删除该约束。 由于约束名称不同,因此在订阅服务器上执行删除操作将会失败。 如果由于约束命名问题而导致同步失败,可以在订阅服务器中手动删除约束然后重新运行合并代理。
如果为复制发布了一个表,并且已生成了发布快照,则无法将该表中的列更改为 XML 数据类型。若要更改列,必须先删除复制。
对已发布的表执行 DDL 时,“读未提交”不是支持的隔离级别。
SET CONTEXT_INFO 不应用于修改针对已发布对象执行架构更改的事务的上下文。
添加列
若要向表添加新列并在现有出版物中包含该列,请执行 ALTER TABLE<表> ADD <列>。 默认情况下,此列然后将被复制到所有订阅服务器中。 此列必须允许 NULL 值或包含默认约束。 有关添加列的更多信息,请参阅本主题中的“合并复制”部分。
若要向表中添加新列而不在现有发布中包含该列,请禁用架构更改复制,然后执行 ALTER TABLE<Table> ADD <Column>。
要将现有列添加到现有发布中,请使用 sp_articlecolumn (Transact-SQL)、sp_mergearticlecolumn (Transact-SQL) 或 “发布属性 - <发布>” 对话框。
有关详细信息,请参阅 Define and Modify a Column Filter。 这要求重新初始化订阅。
不支持向已发布的表中添加标识列,因为当该标识列被复制到订阅服务器时,可能会导致无法收敛。 发布服务器的标识列中的值取决于受影响的表中行的物理存储顺序。 订阅服务器上的行存储方式可能不同;因此,同一行的标识列值可能不同。
删除列
若要从现有发布中删除某列,并在发布服务器上的表中删除该列,请执行 ALTER TABLE<Table> DROP <Column>。 默认情况下,随后会从所有订阅服务器上的表中删除该列。
要从现有发布中删除列但在发布服务器中的表中保留该列,请使用 sp_articlecolumn (Transact-SQL)、sp_mergearticlecolumn (Transact-SQL) 或“发布属性 - <发布>”对话框。
有关详细信息,请参阅 Define and Modify a Column Filter。 这要求生成一个新的快照。
要删除的列不能用于数据库中任何发布的任何项目的筛选子句中。
从已发布的文章中删除列时,请考虑该列中任何可能影响数据库的约束、索引或属性。 例如:
无法从事务发布的项目中删除主键中使用的列,因为这些列由复制使用。
无法从合并发布的项目中删除 rowguid 列,也不能从支持更新订阅的事务性发布的项目中删除 mstran_repl_version 列,因为这些列由复制使用。
索引更改不会传播到订阅服务器:如果在发布服务器上删除某一列,并且依赖该列的索引也被删除,则该索引的删除操作不会被复制。 在发布服务器上删除该列之前,应先在订阅服务器上删除该索引,这样当删除列的操作从发布服务器复制到订阅服务器时,才能成功执行。 如果由于订阅服务器中的索引而导致同步失败,可以手动删除索引然后重新运行合并代理。
约束应显式命名,以允许删除。 有关详细信息,请参阅本主题后面的“一般注意事项”部分。
事务复制
架构更改传播到运行 SQL Server 早期版本的订阅服务器中,但 DDL 语句只应包含订阅服务器中的 SQL Server 版本支持的语法。
如果订阅服务器重新发布数据,唯一支持的架构更改是添加和删除列。 应在发布服务器上使用 sp_repladdcolumn(Transact-SQL) 和 sp_repldropcolumn(Transact-SQL) 进行这些更改,而不是使用 ALTER TABLE DDL 语法。
架构更改不会复制到非 SQL Server 订阅服务器。
来自非 SQL Server 发布服务器的架构更改不会被传播。
无法更改按表复制的索引视图。 作为索引视图复制的索引视图可以修改,但对其进行修改后,它们将变为普通视图,而不再是索引视图。
如果发布支持立即更新订阅或排队更新订阅,则在进行架构更改之前,必须先使系统进入静止状态:必须停止发布服务器和订阅服务器上已发布表的所有活动,并将待处理的数据更改传播到所有节点。 架构更改传播到所有节点后,可以在已发布的表上恢复活动。
如果发布位于对等拓扑中,则必须先将系统置于静止状态,然后才能进行架构变更。 有关详细信息,请参阅停止复制拓扑(复制 Transact-SQL 编程)。
向表中添加时间戳列并将该时间戳映射为 binary(8) 会导致针对所有活动订阅重新初始化该项目。
合并复制
合并复制如何处理架构更改,取决于发布兼容级别,以及快照是设置为本机模式(默认)还是字符模式:
若要复制架构更改,发布的兼容级别必须至少为 90RTM。 如果订阅服务器运行 SQL Server 的早期版本或者兼容级别小于 90RTM,则可以使用 sp_repladdcolumn (Transact-SQL) 和 sp_repldropcolumn (Transact-SQL) 来添加和删除列。 但是,不推荐使用这些过程。
如果试图在现有项目中添加包含 SQL Server 2008 (10.0.x) 中引入的数据类型的列,则 SQL Server 具有以下行为:
100RTM,本机快照 100RTM,角色快照 所有其他兼容级别 hierarchyid 允许修改 阻止更改 阻止更改 geography 和 geometry 允许更改 允许更改* 阻止更改 文件流 (filestream) 允许更改 阻止更改 阻止更改 date、 time、 datetime2和 datetimeoffset 允许更改 允许更改* 阻止更改 *SQL Server Compact 订阅服务器在订阅端转换这些数据类型。
如果在应用架构更改时发生错误(如由于添加的外键引用订阅服务器中不可用的表而导致错误),同步将失败,必须重新初始化订阅。
如果在联接筛选器或参数化筛选器中涉及的列上进行架构更改,必须重新初始化所有订阅并重新生成快照。
合并复制提供了用于在故障排除期间跳过架构更改的存储过程。 有关详细信息,请参阅 sp_markpendingschemachange (Transact-SQL) 和 sp_enumeratependingschemachanges (Transact-SQL)。