事件触发器能捕获到函数中的 DDL 事件吗?
事件触发器对一个特定数据库来说是全局的,并且可以捕捉该数据库中发生的 DDL 事件。Redrock Postgres 提供了函数 pg_ddl_command_deparse,可以将 DDL 命令从pg_ddl_command
类型的内部格式反向解析为 SQL 语句。
在下面的例子中,我们创建了一个事件触发器,在命令结束处捕获该数据库中发生的 DDL 事件。
CREATE OR REPLACE FUNCTION ddl_trigger_func()
RETURNS event_trigger AS $$
DECLARE
ddl record;
BEGIN
FOR ddl IN SELECT * FROM pg_event_trigger_ddl_commands()
LOOP
RAISE NOTICE 'ddl command: %',
pg_ddl_command_deparse(ddl.command);
END LOOP;
END $$ LANGUAGE plpgsql;
CREATE EVENT TRIGGER ddl_event_trigger
ON ddl_command_end
EXECUTE PROCEDURE ddl_trigger_func();
让我们来创建一个函数,在函数体中,往表t_table
插入一条记录,并更改序列t_table_id_seq
的当前值。
CREATE TABLE t_table (id serial, name text);
CREATE OR REPLACE FUNCTION func_with_ddl(num integer)
RETURNS void AS $$
BEGIN
INSERT INTO t_table (id, name) VALUES (num + 1, 'dummy');
EXECUTE format('ALTER SEQUENCE t_table_id_seq RESTART %s', num + 2);
END $$ LANGUAGE plpgsql;
SELECT func_with_ddl(coalesce(max(id), 0)) FROM t_table;
在上面的例子中,我们会发现,即使在函数体中存在 DDL 命令,事件触发器也可以捕捉在函数执行过程中发生的 DDL 事件。