【问题标题】:How to get SQL text from Postgres event trigger如何从 Postgres 事件触发器中获取 SQL 文本
【发布时间】:2019-07-09 04:38:17
【问题描述】:

在标签 ALTER TABLE 上的 pgsql 事件触发器中,我想知道正在更改哪个表。

pg 变量不涵盖这一点,GET STACKED DIAGNOSTICS 公开的变量也不涵盖这一点。

在变量可用的情况下,触发器函数本身是否有任何方法可以查看负责启动函数的 SQL 命令的文本。

例如,如果

ALTER TABLE base1 ADD COLUMN col1 int;

负责调用事件触发器,有没有什么办法可以在事件触发器内看到ALTER TABLE base1 ADD COLUMN col1 int文本本身?

【问题讨论】:

  • SELECT current_query()。但它只会显示 top level 查询,这不一定是触发事件触发器的原因 - 例如,如果您使用 PL/PgSQL 函数执行了ALTER TABLE。事件触发器将被扩展以添加更多关于命令的信息,但目前在 9.3/9.4 中非常有限。
  • @CraigRinger - 谢谢。期待扩展!
  • 如果你用 C 写了一个事件触发器,你也有命令的解析树。 postgresql.org/docs/9.3/static/event-trigger-interface.html 肯定不是依赖它的最佳方法,但在扩展此功能之前,它是某种东西。

标签: postgresql triggers plpgsql


【解决方案1】:

从 PostgreSQL 9.5 开始,函数 pg_event_trigger_ddl_commands() 可用于 ddl_command_end 事件触发器。使用TAG 过滤器,它可以用于处理任何ALTERED 表。 object_identity(或objid)可以用来解决原来知道哪个表被ALTERED的问题。至于获取完整的命令,也可以,不过是内部类型pg_ddl_command。

CREATE TABLE t (n INT);

CREATE FUNCTION notice_event() RETURNS event_trigger AS $$
DECLARE r RECORD;
BEGIN
    FOR r IN SELECT * FROM pg_event_trigger_ddl_commands() LOOP
        RAISE NOTICE 'caught % event on %', r.command_tag, r.object_identity;
    END LOOP;
END;
$$
LANGUAGE plpgsql;

CREATE EVENT TRIGGER tr_notice_alter_table
  ON ddl_command_end WHEN TAG IN ('ALTER TABLE')
  EXECUTE PROCEDURE notice_event();

ALTER TABLE t ADD c CHAR;

输出: NOTICE: caught ALTER TABLE event on public.t

【讨论】:

  • 如果是ddl_command_start,如何获取比tg_tag 和tg_event 更多的数据?
  • 有没有办法获取实际执行的 SQL? pg_event_trigger_ddl_commands() 返回一列 command 但似乎内容无法访问。
  • @a_horse_with_no_name 我认为你可以使用 current_query() 来捕捉它。
猜你喜欢
  • 1970-01-01
  • 2021-09-02
  • 2023-01-05
  • 1970-01-01
  • 2020-07-24
  • 1970-01-01
  • 2017-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多