触发器方式
您可以在创建触发器时将触发器方式设置为启用或禁用触发器。
触发器方式
您可以以 ENABLED 或 DISABLED 方式在表或视图上创建触发器。
- 当以 ENABLED 方式创建触发器时,如果发生触发事件,则数据库服务器执行触发操作。(如果在创建触发器时不指定任何方式,则 ENABLED 是缺省方式。)
- 当以 DISABLED 方式创建触发器时,触发事件不会导致执行触发操作。实际上,数据库服务器将忽略该触发器及其操作。即使 systriggers 系统目录表维护有关已禁用触发器的信息。
您也可以使用 Database Object Mode 语句的 SET TRIGGERS 选项将现有的触发器设置为 ENABLED 或 DISABLED 方式。
通过 SET TRIGGERS 语句启用 DISABLED 触发器后,当发生触发事件时,数据库服务器可以执行触发操作,但是触发器不逆向执行。对于禁用触发器后和启用触发器前这段时间内选择、插入、删除或更新的行,数据库服务器将不试图为其执行触发。
警告: 由于触发器的行为根据其 ENABLED 或 DISABLED 方式而不同,因此禁用触发器时请小心。如果禁用触发器将最终破坏数据库的语义完整性,则请不要禁用触发器。
表层级结构中的触发器继承
缺省情况下,任何您定义在 GBase 8s 的类型表上的触发器都会被它的子表继承。
在此版本的 GBase 8s 中,一个表可以继承多个由同一的触发事件启用的触发器,因此这些触发器都是为子表上的相同类型的事件所定义的。
在所有版本的 GBase 8s 中,您在子表上设置的触发器会被它的依赖表继承,但是不会对它的超级表起作用。
当您需要在超级表上启用触发器,但不在其的子表上禁用时,该行为十分重要。在此版本中,禁用在表层次结构中的表上的触发器不会影响继承触发器。例如,以下语句对在表层次结构中低于或高于 subtable 的表对象上的触发器没有影响:
SET TRIGGERS FOR subtable DISABLED
类似地,DROP TRIGGER 语句不能除去继承的触发器,而不移除超级表上的触发器。在这种情况下,您必须改为在子表上定义一个没有 Action 子句的触发器。因为触发器未启用,此空的触发器会覆盖继承的触发器并对子表和子表下的任何子表执行,这些子表不需要进一步覆盖。
触发器和 SPL 例程
您不能如在数据操纵语言语句中列出的那样,在 DML(数据操纵语言)语句中调用的 SPL 例程中定义触发器。因此,如果 sp_items 过程包含CREATE TRIGGER 语句,则以下语句返回错误:
INSERT INTO items EXECUTE PROCEDURE sp_items;
您不能将 SQL 的 CREATE FUNCTION 或 CREATE PROCEDURE 语句与 REFERENCING 子句一起使用来定义包含 FOR table 或 FOR view 规范的触发器例程。这些 UDR 必须包含在指定的表或视图中为 OLD 或 NEW 列值声明的 correlation 名称的 REFERENCING 子句。表或视图上的触发器可以调用来自 Triggered Action 列表中 FOR EACH ROW 部分的触发器例程。触发器还可以调用来自 Triggered Action 列表 BEFORE 和 AFTER 部分的非触发器例程,但是这些 UDR 不能使用 correlation 名称来引用 NEW 或 OLD 列值。正如 REFERENCING 子句 中描述的那样,触发器例程中的 REFERENCING 子句支持与 CREATE TRIGGER 语句相同的语法。
由同一触发事件执行的多个触发器可调用多个触发例程,并且这些例程可以通过使用具有相同或不同名称的 SPL 变量访问同一 NEW 或 OLD 列值。当一个触发事件执行多个触发器时,不会授权执行的顺序时,但是所有的 BEFORE 触发器操作都会在 FOR EACH ROW 触发操作之前执行,而所有的 AFTER 触发操作会在所有的 FOR EACH ROW 触发操作后执行。
对于不是触发器例程的 UDR ,SPL 变量在 CREATE TRIGGER 语句中无效。触发器调用的 SPL 例程只能在当前数据库的本地表或本地视图上执行 INSERT 、DELETE 或 UPDATE 操作。另请参阅 SPL 例程的规则以获取关于触发操作中调用的 SPL 例程的附加限制的信息。
触发事件
触发器事件指定哪个 DML 语句可以启动触发器。事件可以是表或视图上的 INSERT 、DELETE 或 UPDATE 操作,或是查询表的 SELECT 操作。每个 CREATE TRIGGER 语句必须指定一个触发器事件。作为触发事件的实例的任何 SQL 语句都称为触发语句。
对于每个表,您只能定义一个由 INSERT 、DELETE 、UPDATE 或 SELECT 语句的激活的触发器。对于每个视图,您可以定义定义由 INSERT 、DELETE 或 UPDATE 语句激活的 INSTEAD OF 触发器。同一表或视图上的多个触发器可以被不同类型的触发器事件或同一类型的触发器事件激活。
如果触发表具有指定 ON DELETE CASCADE 的引用约束,则您不能指定 DELETE 事件。
您负责确保触发语句在表上有或没有触发器操作时都返回相同的结果。另请参阅 Action 子句 触发操作部分。
来自外部数据库服务器的触发语句可以激活触发器。
如以下示例所示,newtab 上的 Insert 触发器(由 dbserver1 管理)由来自dbserver2 的 INSERT 语句激活。该触发器就像在 dbserver1 上生成的 INSERT 那样执行。
-- Trigger on stores_demo@dbserver1:newtab
CREATE TRIGGER ins_tr INSERT ON newtab
REFERENCING new AS post_ins
FOR EACH ROW(EXECUTE PROCEDURE nt_pct (post_ins.mc));
-- Triggering statement from dbserver2
INSERT INTO stores_demo@dbserver1:newtab
SELECT item_num, order_num, quantity, stock_num, manu_code,
total_price FROM items;
GBase 8s 也支持视图上的 INSTEAD OF 触发器。这些触发器在一个触发 DML 操作引用该指定视图时被启动。INSTEAD OF 触发器使用视图上指定的触发器操作替换该触发器操作事件,而不是执行触发 INSERT 、DELETE 或 UPDATE 操作。对于每种事件类型(INSERT 、DELETE 或 UPDATE),视图可以至多定义多个 INSTEAD OF 触发器。