【问题标题】:Creating trigger for every new insertion in postgresql为 postgresql 中的每个新插入创建触发器
【发布时间】:2020-07-04 09:45:20
【问题描述】:

我在两个不同的数据库中有两个表 table1 和 table2。现在我创建了一个触发器,每当在 table1 中插入新行时,它将插入到 table2 中。下面是我的触发器

CREATE TRIGGER sync_user_table AFTER INSERT ON table1
for each row execute procedure sync_and_maintain_users_table()

CREATE OR REPLACE function sync_and_maintain_users_table()
returns trigger as
$BODY$
begin
    insert into global_db.public.table2
    values (user_uuid, user_registration_date, user_service_provider);
end;
$BODY$
language plpgsql;

但上述触发器不起作用。我也没有收到任何错误,我不确定出了什么问题。

【问题讨论】:

    标签: postgresql database-trigger


    【解决方案1】:

    创建触发器时可能没有错误,但运行时可能会出现错误:

    CREATE OR REPLACE function sync_and_maintain_users_table()
    returns trigger as
    $BODY$
    begin
        insert into global_db.public.table2
        values (user_uuid, user_registration_date, user_service_provider);
    end;
    $BODY$
    language plpgsql;
    CREATE FUNCTION
    
    CREATE TRIGGER sync_user_table AFTER INSERT ON table1
    for each row execute procedure sync_and_maintain_users_table();
    CREATE TRIGGER
    
    insert into table1 values(1);
    ERROR:  cross-database references are not implemented: "global_db.public.table2"
    LINE 1: insert into global_db.public.table2
                        ^
    QUERY:  insert into global_db.public.table2
        values (user_uuid, user_registration_date, user_service_provider)
    CONTEXT:  PL/pgSQL function sync_and_maintain_users_table() line 3 at SQL statement
    

    在 PostgreSQL 中,您不能使用 database.schema.object 语法直接引用另一个数据库。

    如果你解决了这个问题,你会遇到另一个错误:

    CREATE OR REPLACE function sync_and_maintain_users_table()
    returns trigger as
    $BODY$
    begin
        insert into public.table2
        values (user_uuid, user_registration_date, user_service_provider);
    end;
    $BODY$
    language plpgsql;
    CREATE FUNCTION
    
    insert into table1 values(1);
    ERROR:  column "user_uuid" does not exist
    LINE 2:     values (user_uuid, user_registration_date, user_service_...
                        ^
    HINT:  There is a column named "user_uuid" in table "table2", but it cannot be referenced from this part of the query.
    QUERY:  insert into public.table2
        values (user_uuid, user_registration_date, user_service_provider)
    CONTEXT:  PL/pgSQL function sync_and_maintain_users_table() line 3 at SQL statement
    

    您需要添加代码来初始化 VALUES 子句中使用的变量。 请参阅https://www.postgresql.org/docs/12/plpgsql-trigger.html 中的示例。

    【讨论】:

    • 但是我的一个表在另一个数据库中。那么如何编写此函数以在 table1 上成功插入后插入值?
    • 我已经更改了这样的插入查询insert into global_db.public.table2 values (NEW.user_uuid, NEW.user_registration_date, NEW.user_service_provider);
    • 您可以尝试使用 postgres_fdw 或 dblink 扩展来执行此操作,但请注意确保这是一个好主意,因为您将使用分布式事务。在同一个数据库中使用不同的模式会更容易(PostgreSQL 中相同实例中的数据库的行为不像 SQL Server 中相同实例中的数据库)。
    • 进行上述更改后,我将 table2 添加到同一个数据库和同一个模式中,它仍然无法正常工作
    • A trigger function must return either NULL or a record/row value having exactly the structure of the table the trigger was fired for.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-17
    • 2013-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    • 2021-08-04
    相关资源
    最近更新 更多