本文介绍如何将 Update 语句复制为 DELETE/INSERT 对。
原始产品版本: SQL Server
原始 KB 数: 238254
总结
如果更新属于唯一约束的任何列,SQL Server 会将更新实现为“延迟更新”,这意味着作为一对 DELETE
/INSERT
作。 此“延迟更新”会导致复制向订阅服务器发送一对 DELETE
/INSERT
语句。 还有其他可能导致延迟更新的情况。 因此,在订阅服务器上的触发器或自定义存储过程中UPDATE
实现的任何业务逻辑也应包含在触发器或自定义存储过程中/DELETE
INSERT
。
详细信息
事务复制中的默认行为是使用INSERT
UPDATE
和DELETE
自定义存储过程在订阅服务器上应用更改。
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 实现为一对INSERT
DELETE
/语句,因为要更新col1
,该语句定义了唯一索引。 因此,日志读取器在分发数据库中放置一对 DELETE
/INSERT
调用。 这可能会影响订阅服务器上触发器或自定义存储过程中存在的任何业务逻辑。 应将其他业务逻辑合并到DELETE
INSERT
触发器或存储过程中以处理这种情况。
如果希望将单行更新复制为UPDATE
语句而不是INSERT
DELETE
对,则可以启用跟踪标志 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
,但在订阅服务器上仅应用相应的命令。