CREATE EVENT TRIGGER
功能描述
创建 DDL 触发器。
注意事项
只有超级用户才能创建 DDL 触发器。
在单用户模式下禁用 DDL 触发器。如果错误的 DDL 触发器禁用了数据库而无法取消触发器,请以单用户模式重新启动。
语法格式
CREATE EVENT TRIGGER name
ON event [ ON DATABASE | SCHEMA ]
[ WHEN filter_variable IN (filter_value [, ... ]) [ AND ... ] ]
EXECUTE PROCEDURE function_name()
CREATE EVENT TRIGGER name
{ AFTER LOGON | BEFORE LOGOFF } ON DATABASE
EXECUTE PROCEDURE function_name()
参数说明
name
DDL 触发器名称。在该数据库中这个名称必须唯一。
ON DATABASE
表示 DDL 触发器绑定于 database 对象,LOGON 与 LOGOFF 事件仅支持指定 ON DATABASE。
ON SCHEMA
表示 DDL 触发器绑定于 schema 对象。
event
会触发对给定函数调用的事件名称,分别为 ddl_command_start、ddl_command_end、sql_drop、table_rewrite、LOGON 和 LOGOFF。
ddl_command_start:在 CREATE、ALTER、DROP、SECURITY LABEL、COMMENT、GRANT或 REVOKE 命令执行前触发。
ddl_command_end: 在 CREATE、ALTER、DROP、SECURITY LABEL、COMMENT、GRANT或 REVOKE 命令执行后触发。
sql_drop:为任何删除数据库对象的操作在 ddl_command_end DDL 触发器之前触发。
table_rewrite:在表被命令ALTER TABLE和ALTER TYPE的某些动作重写之前触发。
LOGON:用户登录后触发,仅支持 AFTER LOGON。
LOGOFF:用户登出前触发,仅支持 BEFORE LOGOFF。
filter_variable
用来过滤事件的变量名称。这可以用来限制触发器的触发事件。当前仅支持通过 TAG 过滤。
TAG 是 SQL 命令执行后的客户端的返回值,例如执行 SQL 语句
CREATE TABLE fruit (id INTEGER);
,则返回的 TAG 为 CREATE TABLE。filter_value
与该触发器要为其引发的 filter_variable 相关联的一个值列表。对于 TAG 这表示一个命令标签列表(例如 DROP FUNCTION)。
function_name
一个用户提供的函数。触发器函数需要声明为无参数,且返回类型为 Event Trigger 的函数。
示例
示例1: 创建ddl_command_start DDL 触发器,指定多条命令触发。
1、创建 DDL 触发器函数。
CREATE OR REPLACE FUNCTION eth1()
RETURNS event_trigger
LANGUAGE plpgsql
AS $$ BEGIN
RAISE NOTICE 'test_event_trigger: % %', tg_event, tg_tag;
END;
$$;
2、创建 DDL 触发器。
CREATE EVENT TRIGGER estart ON ddl_command_start WHEN TAG IN ('CREATE TABLE','ALTER TABLE','DROP TABLE') EXECUTE PROCEDURE eth1();
3、执行 DDL 触发器中指定命令CREATE TABLE。
CREATE TABLE t_eventtr(id int);
结果返回如下:
NOTICE: test_event_trigger: ddl_command_start CREATE TABLE
CREATE TABLE
4、执行 DDL 触发器中指定命令ALTER TABLE。
ALTER TABLE t_eventtr RENAME TO t_eventtr_new;
结果返回如下:
NOTICE: test_event_trigger: ddl_command_start ALTER TABLE
ALTER TABLE
5、执行 DDL 触发器中指定命令DROP TABLE。
DROP TABLE t_eventtr_new;
结果返回如下:
NOTICE: test_event_trigger: ddl_command_start DROP TABLE
DROP TABLE
示例2: 创建ddl_command_end DDL 触发器。
1、创建 DDL 触发器函数。
CREATE OR REPLACE FUNCTION eth1()
RETURNS event_trigger
LANGUAGE plpgsql
AS $$ BEGIN
RAISE NOTICE 'test_event_trigger: % %', tg_event, tg_tag;
END;
$$;
2、创建测试表t_eventtr。
CREATE TABLE t_eventtr(id int);
返回结果如下:
NOTICE: test_event_trigger: ddl_command_start CREATE TABLE
CREATE TABLE
3、创建 DDL 触发器。
CREATE EVENT TRIGGER eend ON ddl_command_end EXECUTE PROCEDURE eth1();
4、删除测试表t_eventtr。
DROP TABLE t_eventtr;
结果返回如下:
NOTICE: test_event_trigger: ddl_command_end DROP TABLE
DROP TABLE
示例3: 创建sql_drop DDL 触发器。
1、创建 DDL 触发器函数。
CREATE OR REPLACE FUNCTION test_event_trigger_drop()
RETURNS event_trigger LANGUAGE plpgsql AS $$
DECLARE
obj record;
BEGIN
FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
LOOP
RAISE NOTICE '% dropped object: % %.% %',
tg_tag,
obj.object_type,
obj.schema_name,
obj.object_name,
obj.object_identity;
END LOOP;
END;
$$;
2、创建测试表t_eventtr。
CREATE TABLE t_eventtr(id int);
3、创建 DDL 触发器edrop。
CREATE EVENT TRIGGER edrop ON sql_drop EXECUTE PROCEDURE test_event_trigger_drop();
4、删除表t_eventtr。
DROP TABLE t_eventtr;
结果返回如下:
NOTICE: DROP TABLE dropped object: table public.t_eventtr public.t_eventtr
NOTICE: DROP TABLE dropped object: type public.t_eventtr public.t_eventtr
NOTICE: DROP TABLE dropped object: type public._t_eventtr public.t_eventtr[]
DROP TABLE
示例4: 创建table_rewrite DDL 触发器。
1、创建 DDL 触发器函数。
CREATE OR REPLACE FUNCTION eth1()
RETURNS event_trigger
LANGUAGE plpgsql
AS $$ BEGIN
RAISE NOTICE 'test_event_trigger: % %', tg_event, tg_tag;
END;
$$;
2、创建 DDL 触发器。
CREATE EVENT TRIGGER erewrite ON table_rewrite EXECUTE PROCEDURE eth1();
示例5: 修改 DDL 触发器。
1、创建 DDL 触发器函数。
CREATE OR REPLACE FUNCTION eth1() RETURNS event_trigger AS $$ BEGIN RAISE NOTICE 'test_event_trigger: % %',tg_event,tg_tag; END $$ LANGUAGE plpgsql;
2、创建 DDL 触发器。
CREATE EVENT TRIGGER logon_event_trigger AFTER logon ON database EXECUTE PROCEDURE eth1();
3、执行以下语句修改 DDL 触发器名称。
ALTER EVENT TRIGGER logon_event_trigger RENAME TO test_eventtri_new;
4、系统表中查询改名后的 DDL 触发器。
SELECT * FROM pg_event_trigger WHERE evtname = 'test_eventtri_new';
结果返回如下:
evtname | evtevent | evtowner | evtfoid | evtenabled | isschema | evttags
-------------------+----------+----------+---------+------------+----------+---------
test_eventtri_new | logon | 10 | 18586 | O | f |
(1 row)
示例6: 创建Logon/Logoff系统 DDL 触发器。
1、创建测试表test2。
create table test2(id int,col timestamp);
2、创建触发器函数eth3()和eth4()。
CREATE OR REPLACE FUNCTION eth3()
RETURNS event_trigger
LANGUAGE plpgsql
AS $$ BEGIN
insert into test2 values(1,systimestamp);
END;
$$;
CREATE OR REPLACE FUNCTION eth4()
RETURNS event_trigger
LANGUAGE plpgsql
AS $$ BEGIN
insert into test2 values(2,systimestamp);
END;
$$;
3、创建Logon/Logoff DDL 触发器。
CREATE EVENT TRIGGER logon_eventtri after Logon ON database
EXECUTE PROCEDURE eth3();
CREATE EVENT TRIGGER logoff_eventtri before Logoff ON database
EXECUTE PROCEDURE eth4();
4、退出数据库重新登陆。
\q
退出后在命令行执行登陆命令。
vsql -r
5、查询test2中记录的Logon/Logoff事件。
SELECT * FROM test2;
结果返回如下:
id | col
----+---------------------
2 | 2023-02-16 11:39:30
1 | 2023-02-16 11:39:32
(2 rows)