SQL Server Trigger的使用

本文介绍了SQL Server中的触发器概念及创建语法,包括FOR、AFTER和INSTEAD OF三种触发时机,以及WITH ENCRYPTION、WITH APPEND和NOT FOR REPLICATION等特性。并通过一个示例展示了如何在删除主记录时,级联删除相关子记录。

(1)  触发器(Trigger)语法(转自SQL SERVER2000帮助文档)

创建触发器,触发器是一种特殊的存储过程,在用户试图对指定的表执行指定的数据修改语句时自动执行。Microsoft® SQL Server™ 允许为任何给定的 INSERT、UPDATE 或 DELETE 语句创建多个触发器。

语法

CREATE TRIGGER trigger_name
ON { table | view
}
[ WITH ENCRYPTION ]
{

     { { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDATE ] }
        [ WITH APPEND ]
        [ NOT FOR REPLICATION ]
        AS
        [ { IF UPDATE ( column )
            [ { AND | OR } UPDATE ( column ) ]
                [ ...n ]
        | IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask )
                 { comparison_operator } column_bitmask [ ...n ]
         } ]
        sql_statement [ ...n ]
     }
}

参数

trigger_name

是触发器的名称。触发器名称必须符合标识符规则,并且在数据库中必须唯一。可以选择是否指定触发器所有者名称。

Table | view

是在其上执行触发器的表或视图,有时称为触发器表或触发器视图。可以选择是否指定表或视图的所有者名称。

WITH ENCRYPTION

加密 syscomments 表中包含 CREATE TRIGGER 语句文本的条目。使用 WITH ENCRYPTION 可防止将触发器作为 SQL Server 复制的一部分发布。

AFTER

指定触发器只有在触发 SQL 语句中指定的所有操作都已成功执行后才激发。所有的引用级联操作和约束检查也必须成功完成后,才能执行此触发器。

如果仅指定 FOR 关键字,则 AFTER 是默认设置。

不能在视图上定义 AFTER 触发器。

INSTEAD OF

指定执行触发器而不是执行触发 SQL 语句,从而替代触发语句的操作。

在表或视图上,每个 INSERT、UPDATE 或 DELETE 语句最多可以定义一个 INSTEAD OF 触发器。然而,可以在每个具有 INSTEAD OF 触发器的视图上定义视图。

INSTEAD OF 触发器不能在 WITH CHECK OPTION 的可更新视图上定义。如果向指定了 WITH CHECK OPTION 选项的可更新视图添加 INSTEAD OF 触发器,SQL Server 将产生一个错误。用户必须用 ALTER VIEW 删除该选项后才能定义 INSTEAD OF 触发器。

{ [DELETE] [,] [INSERT] [,] [UPDATE] }

是指定在表或视图上执行哪些数据修改语句时将激活触发器的关键字。必须至少指定一个选项。在触发器定义中允许使用以任意顺序组合的这些关键字。如果指定的选项多于一个,需用逗号分隔这些选项。

对于 INSTEAD OF 触发器,不允许在具有 ON DELETE 级联操作引用关系的表上使用 DELETE 选项。同样,也不允许在具有 ON UPDATE 级联操作引用关系的表上使用 UPDATE 选项。

WITH APPEND

指定应该添加现有类型的其它触发器。只有当兼容级别是 65 或更低时,才需要使用该可选子句。如果兼容级别是 70 或更高,则不必使用 WITH APPEND 子句添加现有类型的其它触发器(这是兼容级别设置为 70 或更高的 CREATE TRIGGER 的默认行为)。有关更多信息,请参见 sp_dbcmptlevel

WITH APPEND 不能与 INSTEAD OF 触发器一起使用,或者,如果显式声明 AFTER 触发器,也不能使用该子句。只有当出于向后兼容而指定 FOR 时(没有 INSTEAD OF 或 AFTER),才能使用 WITH APPEND。以后的版本将不支持 WITH APPEND 和 FOR(将被解释为 AFTER)。

NOT FOR REPLICATION

表示当复制进程更改触发器所涉及的表时,不应执行该触发器。

AS

是触发器要执行的操作。

sql_statement

是触发器的条件和操作。触发器条件指定其它准则,以确定 DELETE、INSERT 或 UPDATE 语句是否导致执行触发器操作。

当尝试 DELETE、INSERT 或 UPDATE 操作时,Transact-SQL语句中指定的触发器操作将生效。

触发器可以包含任意数量和种类的 Transact-SQL 语句。触发器旨在根据数据修改语句检查或更改数据;它不应将数据返回给用户。触发器中的 Transact-SQL 语句常常包含控制流语言。CREATE TRIGGER 语句中使用几个特殊的表:

  • deletedinserted 是逻辑(概念)表。这些表在结构上类似于定义触发器的表(也就是在其中尝试用户操作的表);这些表用于保存用户操作可能更改的行的旧值或新值。例如,若要检索 deleted 表中的所有值,请使用:
    SELECT *
    FROM deleted
    
  • 如果兼容级别等于 70,那么在 DELETE、INSERT 或 UPDATE 触发器中,SQL Server 将不允许引用 inserteddeleted 表中的 textntextimage 列。不能访问 inserteddeleted 表中的 textntextimage 值。若要在 INSERT 或 UPDATE 触发器中检索新值,请将 inserted 表与原始更新表联接。当兼容级别是 65 或更低时,对 inserteddeleted 表中允许空值的textntextimage 列,将返回空值;如果这些列不可为空,则返回零长度字符串。

    当兼容级别是 80 或更高时,SQL Server 允许在表或视图上通过 INSTEAD OF 触发器更新 textntextimage 列。

n

是表示触发器中可以包含多条 Transact-SQL 语句的占位符。对于 IF UPDATE (column) 语句,可以通过重复 UPDATE (column) 子句包含多列。

IF UPDATE (column)

测试在指定的列上进行的 INSERT 或 UPDATE 操作,不能用于 DELETE 操作。可以指定多列。因为在 ON 子句中指定了表名,所以在 IF UPDATE 子句中的列名前不要包含表名。若要测试在多个列上进行的 INSERT 或 UPDATE 操作,请在第一个操作后指定单独的 UPDATE(column) 子句。在 INSERT 操作中 IF UPDATE 将返回 TRUE 值,因为这些列插入了显式值或隐性 (NULL) 值。

 

说明   IF UPDATE (column) 子句的功能等同于 IF、IF...ELSE 或 WHILE 语句,并且可以使用 BEGIN...END 语句块。有关更多信息,请参见控制流语言

 

可以在触发器主体中的任意位置使用 UPDATE (column)。

column

是要测试 INSERT 或 UPDATE 操作的列名。该列可以是 SQL Server 支持的任何数据类型。但是,计算列不能用于该环境中。有关更多信息,请参见数据类型

IF (COLUMNS_UPDATED())

测试是否插入或更新了提及的列,仅用于 INSERT 或 UPDATE 触发器中。COLUMNS_UPDATED 返回 varbinary 位模式,表示插入或更新了表中的哪些列。

COLUMNS_UPDATED 函数以从左到右的顺序返回位,最左边的为最不重要的位。最左边的位表示表中的第一列;向右的下一位表示第二列,依此类推。如果在表上创建的触发器包含 8 列以上,则 COLUMNS_UPDATED 返回多个字节,最左边的为最不重要的字节。在 INSERT 操作中 COLUMNS_UPDATED 将对所有列返回 TRUE 值,因为这些列插入了显式值或隐性 (NULL) 值。

可以在触发器主体中的任意位置使用 COLUMNS_UPDATED。

bitwise_operator

是用于比较运算的位运算符。

updated_bitmask

是整型位掩码,表示实际更新或插入的列。例如,表 t1 包含列 C1C2C3C4C5。假定表 t1 上有 UPDATE 触发器,若要检查列 C2、C3 C4 是否都有更新,指定值 14;若要检查是否只有列 C2 有更新,指定值 2。

comparison_operator

是比较运算符。使用等号 (=) 检查 updated_bitmask 中指定的所有列是否都实际进行了更新。使用大于号 (>) 检查 updated_bitmask 中指定的任一列或某些列是否已更新。

column_bitmask

是要检查的列的整型位掩码,用来检查是否已更新或插入了这些列。

 

 

 

 

(2)Sample


/********************************************************************************************************************** 
 Name:  Tri_Del_SalesOrder 
 
 Author:  ****
  
 Description: Delete all related child records if SalesOrder record is deleted 
 
 History: 
 Date              Name       Description 
 05/06/2009   ****        Trigger created 
 
**********************************************************************************************************************/ 
 
CREATE TRIGGER [Tri_Del_SalesOrder] ON [dbo].[SalesOrder]  
FOR DELETE  
AS 
 
 IF (SELECT COUNT(*) FROM DELETED) > 0 
 BEGIN 
  DELETE FROM SOProduct WHERE iSOID IN (SELECT iSOID FROM DELETED) 
  DELETE FROM SOQuotation WHERE iSOID IN (SELECT iSOID FROM DELETED) 
  DELETE FROM SOProductSet WHERE iSOID IN (SELECT iSOID FROM DELETED) 
  DELETE FROM SOImprint WHERE iSOID IN (SELECT iSOID FROM DELETED) 
  DELETE FROM SOShipLotDtl WHERE iSOID IN (SELECT iSOID FROM DELETED) 
  DELETE FROM SOItemBreakdownDtl WHERE iSOID IN (SELECT iSOID FROM DELETED) 
 END

<think>好的,我现在需要帮助用户解决关于Oracle GoldenGate(OGG)与SQL Server触发器相关的配置或问题。首先,我需要回顾用户的问题和提供的引用内容,确保回答准确。 用户的问题是关于OGG和SQL Server触发器的配置或问题解决方案。根据用户提供的引用,其中提到了DDL处理、参数设置、性能调整等。但用户特别关注的是触发器相关的配置或问题,因此我需要集中在这方面。 首先,我应该考虑OGG在同步数据时如何处理触发器。通常,数据库触发器会在数据变更时自动执行,但OGG作为数据复制工具,可能会与触发器产生冲突,导致重复操作或数据不一致。例如,如果源数据库的触发器在插入数据时触发了某些操作,而OGG将数据复制到目标数据库时,可能再次触发目标数据库的触发器,这可能是用户关心的问题。 根据引用[3],OGG默认情况下会忽略由自身生成的DDL操作,通过注释/* GOLDENGATE_DDL_REPLICATION */来标识。这可能涉及到在配置时需要排除触发器相关的DDL,或者在复制过程中避免捕获触发器产生的变更。因此,在配置OGG时,可能需要设置参数来忽略触发器,或者在目标端禁用触发器以避免冲突。 接下来,我需要考虑配置步骤。例如,在Extract进程中排除触发器的DDL,或者在Replicat进程中禁用触发器的执行。引用[3]中的GETREPLICATES和IGNOREREPLICATES选项可能与此相关,需要确认这些参数是否影响触发器的处理。 另外,性能方面,引用[4]提到调整OGG性能的方法,包括检查点状态和进程状态。如果触发器导致性能问题,可能需要监控Replicat进程的状态,确保复制没有因触发器而延迟或失败。 可能的解决方案包括在目标数据库禁用触发器,或在OGG配置中排除触发器的DDL。同时,需要确保数据一致性,例如使用用户令牌或在日志中记录额外信息来区分OGG操作和应用程序操作。 此外,用户可能遇到触发器导致的数据冲突或循环触发问题。例如,OGG复制的数据可能再次触发目标触发器,导致无限循环。因此,配置时需要在目标数据库禁用触发器,或修改触发器逻辑,检查操作来源是否为OGG。 总结步骤:1. 配置OGG排除触发器DDL;2. 目标端禁用触发器;3. 使用附加日志避免触发器冲突;4. 处理潜在的数据一致性问题和性能影响。 最后,生成相关问题,帮助用户进一步探索,如触发器导致的数据冲突解决方法,或DDL同步注意事项。</think>### Oracle GoldenGate与SQL Server触发器的配置及问题解决 #### 1. **触发器与OGG的冲突处理** 在Oracle GoldenGate(OGG)与SQL Server集成时,触发器可能导致数据同步冲突。例如,源端触发器修改数据后,OGG会捕获这些变更并复制到目标端,而目标端触发器可能再次触发相同操作,导致数据重复或逻辑错误[^3]。 **解决方案**: - **禁用目标端触发器**:在目标数据库的复制表中禁用触发器,确保OGG同步的数据不会再次触发逻辑。 ```sql DISABLE TRIGGER [TriggerName] ON [TableName]; ``` - **通过OGG过滤触发器操作**:在Extract配置中使用`IGNOREREPLICATES`选项(默认启用),忽略OGG自身生成的DDL操作,避免触发器相关的DDL被捕获[^3]。 --- #### 2. **配置OGG排除触发器DDL** 若需同步表结构但排除触发器,需在OGG配置中显式排除触发器的DDL语句。 **配置步骤**: 1. **修改Extract参数文件**: ```sql TRANLOGOPTIONS EXCLUDETAG 0x8000 -- 排除OGG内部标记的操作 DDLEXCLUDE OBJTYPE TRIGGER -- 排除所有触发器DDL ``` 2. **验证DDL同步**: 使用`INFO EXTRACT <group>, DETAIL`命令检查DDL过滤状态[^4]。 --- #### 3. **处理触发器导致的数据一致性问题** 若目标端需保留触发器,需确保OGG同步的数据不会破坏触发器逻辑。 **方法**: - **附加日志补充数据**:在OGG配置中添加`ADD TRANDATA`命令,确保触发器所需的字段被完整记录在事务日志中[^1]。 - **使用`USERTOKEN`标识OGG操作**:在Replicat进程中添加用户令牌,触发器通过判断该令牌决定是否执行。 ```sql MAP [Schema].[Table], TARGET [Schema].[Table], COLMAP (..., USERTOKEN = 'OGG'); ``` --- #### 4. **性能优化与监控** 触发器的存在可能影响OGG同步性能,需针对性优化。 **建议**: - **检查Replicat延迟**:使用`SEND REPLICAT <group>, STATUS`监控进程状态,确保无阻塞[^4]。 - **批量提交减少开销**:在Replicat参数中设置`BATCHSQL`以提高事务处理效率。 ```sql REPLICAT <group> BATCHSQL ON ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值