对发布数据库进行架构更改

适用于:SQL Server Azure SQL 托管实例

复制支持对已发布对象进行多种架构更改。 对 Microsoft SQL Server 发布服务器中相应的发布对象进行下列任何一种架构更改时,默认会将该更改传播到所有 SQL Server 订阅服务器:

  • ALTER TABLE

  • 如果已启用架构更改复制,并且拓扑包括 SQL Server 2005 (9.x) 或 SQL Server Compact 3.5 订阅服务器,则不应使用 ALTER TABLE SET LOCK ESCALATION。

  • ALTER VIEW

  • ALTER PROCEDURE

  • ALTER FUNCTION

  • ALTER TRIGGER

    由于无法复制数据定义语言 [DDL] 触发器,ALTER TRIGGER 只能用于数据操作语言 [DML] 触发器。

重要

对表进行架构更改时必须使用 Transact-SQL 或 SQL Server 管理对象 (SMO)。 在 SQL Server Management Studio 中进行架构更改时,Management Studio 将尝试删除并重新创建表。 因为无法删除已发布的对象,所以架构更改失败。

对于事务复制和合并复制,当分发代理或合并代理运行时,将增量传播架构更改。 对于快照复制,将在订阅服务器中应用新快照时传播架构更改。 在快照复制中,每次发生同步时,都将架构的一个新副本发送到订阅服务器。 因此,每次同步时都自动传播对以前发布的对象的所有架构更改(而不只是上面列出的那些)。

有关在发布中添加和删除项目的信息,请参阅向现有发布添加项目和从中删除项目

复制架构更改

默认情况下会复制上面列出的架构更改。 有关禁止复制架构更改的信息,请参阅 Replicate Schema Changes

架构更改的注意事项

复制架构更改时,请牢记下列注意事项:

一般注意事项

  • 架构更改需遵守 Transact-SQL 规定的所有限制。 例如,ALTER TABLE 不允许对主键列执行 ALTER 语句。

  • 仅对初始快照执行数据类型映射。 架构更改不会映射到以前版本的数据类型。 例如,如果在 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 <Table> ADD <Column>。 默认情况下,此列然后将被复制到所有订阅服务器中。 此列必须允许 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 允许更改 阻止更改 阻止更改
      geographygeometry 允许更改 允许更改* 阻止更改
      文件流 (filestream) 允许更改 阻止更改 阻止更改
      datetimedatetime2datetimeoffset 允许更改 允许更改* 阻止更改

      *SQL Server Compact 订阅服务器在订阅服务器中转换这些数据类型。

  • 如果在应用架构更改时发生错误(如由于添加的外键引用订阅服务器中不可用的表而导致错误),同步将失败,必须重新初始化订阅。

  • 如果在联接筛选器或参数化筛选器中涉及的列上进行架构更改,必须重新初始化所有订阅并重新生成快照。

  • 合并复制提供了在排除故障期间跳过架构更改的存储过程。 有关详细信息,请参阅 sp_markpendingschemachange (Transact-SQL)sp_enumeratependingschemachanges (Transact-SQL)