系统触发器

系统触发器(System Trigger)是PolarDB PostgreSQL版(兼容Oracle)提供的一种用于监听数据库事件的触发器,能够在发生系统事件时被触发,便于实现复杂的审计逻辑、规则校验或自动化运维操作。本文为您介绍系统触发器的语法、属性函数及其行为特点。

版本限制

仅支持Oracle语法兼容 2.0且内核小版本为2.0.14.15.31.0及以上。

说明

您可在控制台查看内核小版本号,也可以通过SHOW polardb_version;语句查看。如未满足内核小版本要求,请升级内核小版本

基本语法

系统触发器的定义语法如下:

CREATE [OR REPLACE] TRIGGER [schema_name.]trigger_name
{ BEFORE | AFTER | INSTEAD OF }
{ CREATE | ALTER | DROP }
ON { [schema_name.]SCHEMA | DATABASE }
DECLARE
    -- 可选的变量声明
BEGIN
    -- 触发器逻辑
END;

语法

说明

[schema_name.]trigger_name

自定义系统触发器名称。PolarDB的系统触发器是数据库级别的对象,不属于任何一个 Schema,此处的schema_name仅做语法兼容,无实际含义。

  • 自定义系统触发器名称不支持使用_polar_evt_tg_on_db_polar_evt_tg_on_schema,这两个名称为系统保留。

  • 如果已经创建了系统触发器,不允许创建名为_polar_evt_tg_触发器名的函数或存储过程。

{ BEFORE | AFTER | INSTEAD OF }

定义系统触发器触发时机。支持3种类型:

  • BEFORE:在事件之前触发。

  • AFTER:在事件之后触发。

  • INSTEAD OF:取代原逻辑。

{ CREATE | ALTER | DROP }

触发事件类型。

  • 目前仅支持CREATE、ALTER、DROPDDL四类事件,其中DDL表示涵盖了CREATE、ALTERDROP事件。

  • 并非所有DDL都会触发触发器,以下DDL命令不会触发系统触发器。

    • ROLE、USER等全局对象的DDL命令。

    • ALTER SESSION、ALTER SYSTEM、VACUUMDDL命令。

  • INSTEAD OF触发器仅支持CREATE事件。

ON { [schema_name.]SCHEMA | DATABASE }

触发范围。

  • ON DATABASE:表示对当前数据库内各个Schema中发生的事件都触发。

  • ON [schema_name.]SCHEMA:可以限定只对特定Schema中的操作触发。

  • ON SCHEMA:表示对当前Schema触发,这里的当前Schema指当前search_path中的第一个合法Schema。

使用示例如下,该触发器在数据库中任意对象被创建或删除时打印日志。

CREATE OR REPLACE TRIGGER audit_ddl_trigger
AFTER CREATE OR DROP
ON DATABASE
BEGIN
    DBMS_OUTPUT.PUT_LINE('DDL Trigger fired: ' || ORA_SYSEVENT || ' on ' || ORA_DICT_OBJ_NAME || ' of type ' || ORA_DICT_OBJ_TYPE);
END;

事件属性函数

PolarDB PostgreSQL版(兼容Oracle)的系统触发器提供了一系列事件属性函数(Event Attribute Functions),用于获取当前触发事件的上下文信息,通常用于审计和日志记录。

  • ora_sysevent:DDL语句的类型,包括CREATE、ALTERDROP。

  • ora_dict_obj_type:DDL语句操作的对象类型,包括TABLE、VIEW、INDEX等对象。

  • ora_dict_obj_name:DDL语句操作的对象名称。

  • ora_dict_obj_owner:DDL语句操作的对象的所有者,目前仅支持获取TABLE、VIEW、INDEX等对象类型的所有者。

使用示例如下,创建一个系统触发器,用于在DDL语句执行前打印日志。

CREATE OR REPLACE EDITIONABLE TRIGGER trigger_before_ddl before ddl on schema
BEGIN
    dbms_output.put_line('before ddl ora_sysevent: ' || ora_sysevent);
    dbms_output.put_line('before ddl ora_dict_obj_owner: ' || ora_dict_obj_OWNER);
    dbms_output.put_line('before ddl ora_dict_obj_type: ' || ora_dict_obj_type);
    dbms_output.put_line('before ddl ora_dict_obj_name: ' || ora_dict_obj_name);
END;

执行CREATE TABLE test_table (id int);语句,触发器输出结果如下:

before ddl ora_sysevent: CREATE
before ddl ora_dict_obj_owner: test_user
before ddl ora_dict_obj_type: TABLE
before ddl ora_dict_obj_name: test_table

触发器管理

  • 修改触发器定义

    执行CREATE OR REPLACE TRIGGER <trigger_name> ...语句即可替换掉此前的同名触发器的定义,实现触发器定义修改。

  • 启用/禁用触发器

    使用CREATE TRIGGER语句创建的触发器默认启用。

    • 禁用触发器:ALTER TRIGGER <trigger_name> DISABLE;

    • 启用触发器:ALTER TRIGGER <trigger_name> ENABLE;

  • 删除触发器

    执行DROP EVENT TRIGGER <trigger_name>;语句即可删除触发器。