通常,远程数据库与统一数据库定义了相同的触发器。
缺省情况下,SQL Remote 不复制由触发器执行的操作。实际上,当在远程数据库上对在统一数据库中触发触发器的操作进行复制时,复制触发器将在远程数据库上自动触发。这将避免权限问题以及每个操作发生两次的可能性。此规则有一些例外情况:
RESOLVE UPDATE 触发器的复制 由冲突解决或 RESOLVE UPDATE 触发器执行的操作将从统一数据库复制 到所有远程数据库,包括发送引起冲突的消息的远程数据库。请参见更新冲突的缺省解决方法。
BEFORE 触发器的复制 修改要更新的行的 BEFORE 触发器的操作会在执行 UPDATE 语句操作前进行复制。
例如,增加行中计数器列以跟踪行的更新次数的 BEFORE UPDATE 触发器如果被复制,则将进行双倍计数,因为复制 UPDATE 语句时将在远程数据库上触发 BEFORE UPDATE 触发器。
将列设置为上次更新时间的 BEFORE UPDATE 触发器也将获取复制 UPDATE 语句的时间。
若要防止此问题,必须确保预订者数据库中没有 BEFORE UPDATE 触发器,或该触发器不执行被复制的操作。
要在发送消息时复制所有触发器操作,请使用消息代理 (dbremote) 的 -t 选项。请参见消息代理 (dbremote)。
使用 -t 选项时,请确保触发器操作不会在远程数据库中执行两次(一次在执行复制触发器操作时,一次在远程数据库上触发触发器时)。
要确保触发器操作不会执行两次,请使用以下选项之一:
使用 IF CURRENT REMOTE USER IS NULL ...END IF 语句包裹触发器主体。
将 SQL Remote 用户名的 SQL Anywhere fire_triggers 选项设置为 Off。请参见fire_triggers 选项 [兼容性]。
如果发布只包含数据库的子集,则统一数据库中的触发器可能仅引用存在于统一数据库而不存在于远程数据库的表或行。当这样的触发器在远程数据库上触发时,会发生错误。要避免这些错误,请使用 IF 语句以使触发器操作附有条件,并:
使触发器的操作以 CURRENT PUBLISHER 的值为条件。请参见CURRENT PUBLISHER 特殊值。
使触发器的操作以不返回 NULL 的 object_id 函数为条件。object_id 函数将表或其它对象视为参数,并返回该对象的 ID 号;如果该对象不存在,则返回 NULL。请参见系统函数。
使触发器的操作以确定行是否存在的 SELECT 语句为条件。
缺省情况下,数据库抽取实用程序 (dbxtract) 和 [抽取数据库向导] 会抽取触发器定义。
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |