UPDATE 语句可以复制为 DELETE/INSERT 对

本文介绍如何将 Update 语句复制为 DELETE/INSERT 对。

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

总结

如果更新属于唯一约束的任何列,SQL Server 会将更新实现为“延迟更新”,这意味着作为一对 DELETE/INSERT 作。 此“延迟更新”会导致复制向订阅服务器发送一对 DELETE/INSERT 语句。 还有其他可能导致延迟更新的情况。 因此,在订阅服务器上的触发器或自定义存储过程中UPDATE实现的任何业务逻辑也应包含在触发器或自定义存储过程中/DELETEINSERT

详细信息

事务复制中的默认行为是使用INSERTUPDATEDELETE自定义存储过程在订阅服务器上应用更改。

INSERT 发布服务器上的语句通过 INSERT 存储过程调用应用于订阅服务器。 同样, DELETE 语句通过 DELETE 存储过程调用应用。

但是,当语句作为“延迟更新”执行时 UPDATE ,日志读取器代理会在分发数据库中放置一对 DELETE/INSERT 存储过程调用,以应用于订阅服务器,而不是更新存储过程调用。 例如,假设你有一个发布表(命名 TABLE1),其中包含以下三列:

  • col1 int
  • col2 int
  • col3 varchar(30)

唯一唯一的约束 TABLE1 是通过主键约束定义的 col1 。 假设你有一条记录(1,1,达拉斯)。

执行以下代码时:

UPDATE TABLE1 set col1 = 3 where col3 = 'Dallas'

UPDATE语句由 SQL Server 实现为一对INSERTDELETE/语句,因为要更新col1,该语句定义了唯一索引。 因此,日志读取器在分发数据库中放置一对 DELETE/INSERT 调用。 这可能会影响订阅服务器上触发器或自定义存储过程中存在的任何业务逻辑。 应将其他业务逻辑合并到DELETEINSERT触发器或存储过程中以处理这种情况。

如果希望将单行更新复制为UPDATE语句而不是INSERTDELETE对,则可以启用跟踪标志 8207

此外,如果在发布中使用水平筛选器,并且更新后的行不满足筛选条件,则只会向订阅者发送过程 DELETE 调用。 如果以前更新的行不符合筛选条件,但满足更新后的条件,则仅 INSERT 通过复制过程发送过程调用。

在前面的示例中,假设你还定义了 TABLE1一个水平筛选器: where col3 = 'Dallas'。 如果执行以下代码:

UPDATE table1 set col3 = 'New York' where col1 = 3

日志读取器代理仅将 DELETE 存储过程调用应用于订阅服务器,因为更新后的行不符合水平筛选条件。

现在,如果执行以下代码:

UPDATE table1 set col3 = 'Dallas' where col1 = 3

日志读取器仅 INSERT 生成存储过程调用,因为该行以前未满足筛选器条件。

尽管在发布服务器上执行了作 UPDATE ,但在订阅服务器上仅应用相应的命令。