人大金仓数据库KingbaseES 事件触发器

金仓数据库KingbaseES 事件触发器

关键字

KingbaseES、PLSQL、事件触发器、人大金仓

事件触发器概述

触发器是一种数据库技术,它可以在数据库中发生特定事件时触发自动响应。这种技术可以用于监控数据库中的操作,记录事件,或在特定事件发生时自动采取行动。在KingbaseES中,根据依赖的触发对象不同,触发器可以分为两种:表级触发器和事件触发器。其中,表级触发器依赖于已创建的表,对特定表的相关操作,如INSERT、UPDATE、DELETE等会引发触发器调用相应的触发器函数。跟只捕捉DML事件的表级触发器不同,事件触发器依赖于特定的事件,对数据库来说是全局的,它可以捕捉 DDL 事件。本文主要介绍事件触发器。

在数据库中创建了一个事件触发器后,当与该触发器相关联的事件发生时,该触发器就会被触发,从而执行相应的操作。在创建事件触发器时,KingbaseES当前支持下列事件:

(1) ddl_command_start 事件 :该事件在CREATE、ALTER、DROP、SECURITY

LABEL、COMMENT、GRANT 、REVOKE或SELECT INTO命令执行之前发生。对于该事件,事件触发器在触发前并不会检查与这些命令相关联的目标对象是否存在。例如当我们DROP一个并不存在的表时,对应的事件触发器也会触发。但是,当目标对象本身是事件触发器或者全局共享的角色(role)、数据库(database)、表空间(tablespase)时,事件触发器不会触发。例如当我们创建一个数据库时,虽然执行了CREATE命令,但是相应的事件触发器并不会触发。

(2) ddl_command_end 事件:该事件在CREATE、ALTER、DROP、SECURITY

LABEL、COMMENT、GRANT 或REVOKE 命令执行之后,事务提交之前发生。由于该事件是在执行上述命令之后发生的,故发生该事件时的系统表已经被相应的命令更改了。

(3) sql_drop 事件 : 当执行DROP命令后,会先发生sql_drop事件,然后再发生ddl_command_end事件。由于该事件是在DROP命令之后发生的,故被删除的对象已经不在系统表中了,因此发生该事件时不能再从系统表中查询被删除的对象了。

(4)table_rewrite 事件: 该事件在执行命令 ALTER TABLE 和 ALTER TYPE之前发生。其他修改表的控制语句(例如 CLUSTER 和 VACUUM)并不会触发该事件。

事件触发器的使用方法

(1)事件触发器的创建

语法:

CREATE EVENT TRIGGER name ON event

[ WHEN filter_variable IN (filter_value [, ... ]) [ AND ... ] ]

EXECUTE { FUNCTION | PROCEDURE } function_name();

参数解释:

name: 创建的事件触发器的名称,在整个数据库中,该名称必须唯一。

event: 跟所创建的事件触发器相关联的事件,取值可以是:ddl_command_start、ddl_command_end、sql_drop和table_rewrite分别对应前面介绍的那4个事件。

filter_variable: 用来过滤事件触发条件的变量名称。它可以用来限制触发器只在那一些情况下触发。该参数当前唯一支持的取值是 TAG。

filter_value: 与“filter_variable”相关联的一个取值列表。对于 TAG,它表示一个命令标签列表,是一个字符串,例如 'DROP FUNCTION'、'DROP TABLE'等。

function_name: 用户提供的事件触发器函数,该函数不能有参数且返回类型必须是event_trigger。该函数描述了当事件触发器被触发后,所要执行的具体动作。

使用说明:上述语法用来创建一个新的事件触发器。只要指定的事件(event)发生并且与该触发器相关的WHEN条件(如果有)被满足,该触发器的函数将被执行。在上述语法中,使用关键字FUNCTION和PROCEDURE是等价的,但被真实引用的必须是函数,而不是存储过程。

(2)事件触发器的更改

语法:

ALTER EVENT TRIGGER name DISABLE;  --使一个已创建的事件触发器失效

ALTER EVENT TRIGGER name ENABLE [ REPLICA | ALWAYS ];  --使一个已失效的事件触发器重新生效

ALTER EVENT TRIGGER name OWNER TO { new_owner | CURRENT_USER | SESSION_USER }; --更改事件触发器的拥有者(owner)

ALTER EVENT TRIGGER name RENAME TO new_name; --重命名事件触发器

参数解释:

name: 欲更改的事件触发器的名称。

new_owner: 该事件触发器新拥有者的用户名。

new_name: 该事件触发器的新名称。

使用说明:上述语法用来更改一个已创建的事件触发器。一个失效的事件触发器对系统来说仍然是可知的,但是当相应的事件发生时并不会触发它。

(3)事件触发器的删除

语法:

DROP EVENT TRIGGER [ IF EXISTS ] name [ CASCADE | RESTRICT ];

参数解释:

name: 欲删除的事件触发器的名称。

使用说明:使用CASCADE 表明自动删除依赖于该触发器的对象,然后再删除所有依赖于那些对象的其他对象。使用RESTRICT表明如果有任何对象依赖于该触发器,则拒绝删除它。RESTRICT是默认值。

事件触发器的典型示例

下面通过一个事件触发器的使用案例来进一步说明它的用法和功能。

首先创建一个事件触发器函数abort_any_command.

\set SQLTERM /

CREATE OR REPLACE FUNCTION abort_any_command() RETURNS event_trigger AS

BEGIN

    --tg_tag对应相关的命令, 如'CREATE TABLE'、'DROP TABLE'等

    RAISE EXCEPTION 'command % is disabled', tg_tag;

END;

/

然后创建事件触发器abort_ddl,该事件触发器对应ddl_command_start事件,即当该事件发生时,会触发函数abort_any_command中的动作。

\set SQLTERM ;

CREATE EVENT TRIGGER abort_ddl ON ddl_command_start

EXECUTE FUNCTION abort_any_command();

创建该事件触发器后,会禁止执行任何数据定义命令,例如当我们创建一个表t1时会报错。

然后,删除该事件触发器。

DROP EVENT TRIGGER abort_ddl CASCADE;

再去创建表t1, 可以正常创建成功。

重新创建事件触发器abort_ddl,通过WHEN条件指定它只在执行DROP TABLE命令时触发。

CREATE EVENT TRIGGER abort_ddl ON ddl_command_start

WHEN TAG IN ( 'DROP TABLE' )

EXECUTE FUNCTION abort_any_command();

然后去创建表t2, 可以正常创建。

然后删除表t1, 会报错,证明删除表的操作触发了事件触发器abort_ddl。

事件触发器函数

KingbaseES提供了一些系统内置的函数,当事件触发器中的事件发生时,来返回对应事件发生时产生的相关信息,下面分别来介绍。

(1)sys_event_trigger_ddl_commands函数:当ddl_command_end 事件发生时,该函数会返回被每一个用户动作执行的 DDL 命令的列表。该函数只能用在事件触发器中,在其他情况下调用该函数会报错。该函数返回下面的列。

(2) sys_event_trigger_dropped_objects函数:当sql_drop事件发生时,该函数会返回其sql_drop事件中的命令所删除的所有对象的列表。该函数只能用在事件触发器中,在其他情况下调用该函数会报错。该函数返回下面的列。

(3) sys_event_trigger_table_rewrite_oid函数:当table_rewrite事件发生时,该函数会返回要被重写的表的OID。该函数只能用在事件触发器中,在其他情况下调用该函数会报错。

(4) sys_event_trigger_table_rewrite_reason函数:当table_rewrite事件发生时,该函数会返回一个INT值来解释重写原因。这些INT值的确切含义在单独的文档中。该函数只能用在事件触发器中,在其他情况下调用该函数会报错。

下面由一个典型示例来说明上述函数的用法。

首先创建一个事件触发器函数。

\set SQLTERM /

CREATE OR REPLACE FUNCTION test_event_trigger_for_drops() RETURNS event_trigger AS

DECLARE

    obj record;

BEGIN

    --在触发器函数内部调用系统内置函数sys_event_trigger_dropped_objects来返回相关信息

    FOR obj IN SELECT * FROM sys_event_trigger_dropped_objects() LOOP

        RAISE NOTICE 'command % dropped object: OID: %  SCHEMA: %  TYPE: %  NAME: %',

        tg_tag,

        obj.objid,

        obj.schema_name,

        obj.object_type,

        obj.object_name;

    END LOOP;

END;

/

然后创建一个关于事件的事件触发器。

\set SQLTERM ;

CREATE EVENT TRIGGER test_event_trigger_for_drops ON sql_drop

EXECUTE FUNCTION test_event_trigger_for_drops();

创建一个表t1.

CREATE TABLE t1(id INT);

删除表t1.

DROP TABLE t1;

事件触发器test_event_trigger_for_drops触发,输出以下信息。

注: 本文只介绍了KingbaseES中事件触发器的最基本功能和用法,更多关于事件触发器的内容,可参阅KingbaseES的官方手册。

参考资料

《KingbaseES PLSQL过程语言参考手册》

《KingbaseES SQL语言参考手册》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值