【问题标题】:postgres event trigger and function not workingpostgres 事件触发器和功能不起作用
【发布时间】:2018-10-07 06:21:10
【问题描述】:

我寻找一个在创建表后触发的事件触发器。我在这里找到了一些不错的帖子并进行了一些测试。我的问题是没有任何反应,没有错误也没有输出。所以请给我一些建议,我做错了什么。这是我的代码。 我是 postgres 的新手,来自 oracle,所以请原谅我这个可能“简单”的问题。

create table createt (tname char(20));

CREATE OR REPLACE FUNCTION insert()
RETURNS event_trigger
AS $$
DECLARE r RECORD;
BEGIN
r := pg_event_trigger_ddl_commands();
INSERT INTO createt VALUES(r.object_identity);
END;
$$
LANGUAGE plpgsql;

CREATE EVENT TRIGGER insert_event ON ddl_command_end
WHEN TAG IN ('CREATE TABLE')
EXECUTE PROCEDURE insert();

所以在这个测试用例中,我想把新创建的表的表名放在表 createt 中!但什么也没有发生。如何检查触发器是否已启动。或者我该如何调试这个功能?

感谢您的时间和建议。

【问题讨论】:

    标签: postgresql function events plsql triggers


    【解决方案1】:

    函数pg_event_trigger_ddl_commands() 返回一组行。触发器函数必须准备好接受多于一行,例如:

    CREATE OR REPLACE FUNCTION insert()
    RETURNS event_trigger
    AS $$
    BEGIN
        INSERT INTO createt 
        SELECT object_identity
        FROM pg_event_trigger_ddl_commands();
    END;
    $$
    LANGUAGE plpgsql;
    

    char(20) 不够object_identity,使用text

    DROP TABLE createt;
    CREATE TABLE createt (tname text);
    

    当您使用串行主键创建表时会发生什么?

    create table my_table(id serial primary key);
    

    让我们检查一下:

    select *
    from createt
    
             tname          
    ------------------------
     public.my_table_id_seq
     public.my_table
     public.my_table_pkey
     public.my_table_id_seq
    (4 rows)    
    

    序列上有两个动作,第一个是创建它,另一个是设置owned byalter sequence

    【讨论】:

      【解决方案2】:

      感谢您的建议。 关于 object_identity 的行集的很好的解释。 但是为什么表createt中有4行。我希望 3(表名、主键名、索引名)。为什么会有"my_table_id_seq"两次插入?

      所以我用你的代码为我试了一下,但现在我发现函数 pg_event_trigger_ddl_commands 不存在!

      marcel=# DROP TABLE createt;
      FEHLER:  Tabelle »createt« existiert nicht
      marcel=# CREATE TABLE createt (tname text);
      CREATE TABLE
      marcel=#
      marcel=# CREATE OR REPLACE FUNCTION insert()
      marcel-# RETURNS event_trigger
      marcel-# AS $$
      marcel$# BEGIN
      marcel$# INSERT INTO createt
      marcel$# SELECT object_identity
      marcel$# FROM pg_event_trigger_ddl_commands();
      marcel$# END;
      marcel$# $$
      marcel-# LANGUAGE plpgsql;
      CREATE FUNCTION
      marcel=# CREATE EVENT TRIGGER insert_event ON ddl_command_end
      marcel-# WHEN TAG IN ('CREATE TABLE')
      marcel-# EXECUTE PROCEDURE insert();
      CREATE EVENT TRIGGER
      marcel=#
      marcel=#
      marcel=# create table my_table(id serial primary key);
      FEHLER:  Funktion pg_event_trigger_ddl_commands() existiert nicht
      ZEILE 3: FROM pg_event_trigger_ddl_commands()
                    ^
      TIP:  Keine Funktion stimmt mit dem angegebenen Namen und den Argumenttypen überein. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen.
      ANFRAGE:  INSERT INTO createt
      SELECT object_identity
      FROM pg_event_trigger_ddl_commands()
      KONTEXT:  PL/pgSQL-Funktion insert() Zeile 3 bei SQL-Anweisung
      marcel=#
      marcel=# select * from createt;
       tname
      -------
      (0 Zeilen)
      

      【讨论】:

      • 函数 pg_event_trigger_ddl_commands() 在 Postgres 9.5 中被引入。你的服务器是什么版本的?
      • 我有 9.4.15... 这说明了一切 ;)
      • 你能回答为什么这个表有 4 行吗?还有另一种方法可以解决我的版本中缺少的功能吗?啊……我看到你的更新了。谢谢你。
      • 查看更新的答案,我在末尾添加了注释。
      猜你喜欢
      • 2021-07-31
      • 1970-01-01
      • 2021-10-25
      • 2013-01-05
      • 1970-01-01
      • 2018-08-13
      • 1970-01-01
      • 2018-08-10
      • 1970-01-01
      相关资源
      最近更新 更多