使用 Microsoft SQL Server 进行复制时,Oracle 发布触发器发送非发布的列的数据

本文可帮助你解决将事务复制与 Oracle 发布服务器和列筛选配合使用时发生的问题。

原始产品版本:SQL Server
原始 KB 数: 2310152

现象

将事务复制与 Oracle 发布服务器和列筛选结合使用时,你会注意到发布向导(行级别触发器)生成的触发器跟踪表的所有列,即使只发布少数列。

原因

当垂直筛选器应用于使用配置网关选项的 Oracle 发布服务器创建的发布时,SQL Server 将跟踪表限制为仅包含感兴趣的列,但不限制触发事件。 因此,如果对跟踪表中未包含的表列进行许多更新,则许多不必要的行将记录到跟踪表中。

解决方法

可以通过在复制设置过程中手动更改 Oracle 数据库上生成的数据库触发器来解决此问题,以包含显式列列表来限制更新时发生的列将导致触发器触发。

使用以下过程实现解决方法:

  1. 验证 Oracle 发布服务器是否已配置为网关发布服务器
  2. 将已发布表或其关联的表空间标记为只读。
  3. 确定与已发布表关联的行触发器和日志表的名称。
  4. 修改行触发器的子句,该子句标识激发条件以包含仅包含已发布列的显式列列表。
  5. 还原已发布表或其关联的表空间以读取写入。

有关每个步骤的详细信息,请参阅以下段落:

如何将已发布表或其关联的表空间标记为只读:

在修改触发器之前,需要将表设置为只读,以便不会丢失任何更改。 如果 Oracle 版本早于 11 g,则需要将与表关联的表空间标记为只读。 使表空间只读可防止对表空间中的数据文件执行写入操作。 若要确定与已发布表关联的表空间,请运行以下查询:

select table_name, tablespace_name from all_tables

where table_name = 'my_table' and owner = 'my_name';

若要使数据文件只读,请使用类似于以下内容的命令:

ALTER TABLESPACE my_tablespace READ ONLY;

在 Oracle 11 g 中,可以直接将表标记为只读。

ALTER TABLE my_table READ ONLY;

如何将已发布表或其关联的表空间标记为只读:

在修改触发器之前,需要将表设置为只读,以便不会丢失任何更改。 如果 Oracle 版本早于 11 g,则需要将与表关联的表空间标记为只读。 使表空间只读可防止对表空间中的数据文件执行写入操作。 若要确定与已发布表关联的表空间,请运行以下查询:

select table_name, tablespace_name from all_tables

where table_name = 'my_table' and owner = 'my_name';

若要使数据文件只读,请使用类似于以下内容的命令:

ALTER TABLESPACE my_tablespace READ ONLY;

在 Oracle 11 g 中,可以直接将表标记为只读。

ALTER TABLE my_table READ ONLY;

如何确定与已发布表关联的行触发器和日志表的名称:

所有日志表和触发器都具有从以下模板构造的名称:

  • HREPL_ARTICLE N LOG_ V

  • HREPL_ARTICLE N_TRIGGER_ROW

其中 N 和 V 按以下方式确定:

N 是与已发布表关联的article_id,可以使用分发服务器上以下 SQL 查询获取该表:

select name, table_id from distribution.dbo.IHarticles

V 是版本设计器。 如果两个日志表的 N 关联值相同,则活动日志具有更大的 V 值。

如何修改行触发器的子句,该子句标识激发条件以包含仅包含已发布列的显式列列表:

Oracle 提供了一个名为 SQL 开发人员的免费 GUI 工具,非常适合对生成的触发器进行所需的修改。 可以使用 SQL 开发人员工具中的以下步骤进行必要的修改:

  1. 打开与 Oracle 实例的连接。

  2. 在定义的 Oracle 架构下,扩展与复制管理员用户对应的架构。

  3. 在对象列表中找到触发器,然后展开该触发器以查看复制管理员用户拥有的触发器列表。

  4. 找到要修改的触发器并突出显示它。 触发器的文本将显示在右窗格中。

  5. 右键单击列表中的触发器名称,然后选择“编辑”

  6. 对触发器定义的更改接近触发器的开头,如下所示:

    • ..在删除或插入或更新后创建或替换触发器

    • my_name.my_table

    • 对于每行...

  7. 若要修改触发器,请在 UPDATE 关键字后面包括文章中包含的已发布表中的列列表。 如果在 repl 管理员架构下展开“表”,然后展开与已发布表关联的项目日志表,则要包含的列显示在日志中之后,前面有五个初始元数据列,这些列以HREPL_开头。 ON 一词应显示在列列表的开头。 下面显示了具有已发布列 PK、c1 和 c2 的表 my_name.my_table 所需的修改。

    create or replace TRIGGER AFTER DELETE OR INSERT OR UPDATE ON "PK", "c1", "c2" OF my_name.my_table FOR EACH ROW...
    
  8. 完成修改后,右键单击触发器名称并选择编译以编译修订后的触发器。 确保生成的触发器在编译后标识为有效。

如何还原已发布表或其关联的表空间以读取写入:

完成对触发器的修改后,请确保将表空间或表还原为 READ WRITE,具体取决于标记为只读。 以下语句使my_tablespace表空间可写:

ALTER TABLESPACE *my_tablespace* READ WRITE;

在 Oracle 11 g 中,使用 alter table 命令还原表以允许修改:

ALTER TABLE *my_table*  READ WRITE;

在 Oracle 11 g 中使用以下查询来验证已发布表是否不再为只读:

select table_name, read_only

from dba_tables

where table_name = 'my_table' and owner = 'my_owner'

第三方免责声明

第三方信息免责声明

本文中提到的第三方产品由 Microsoft 以外的其他公司提供。 Microsoft 不对这些产品的性能或可靠性提供任何明示或暗示性担保。