Postgresql:在外部表上触发以执行截断/插入本地表的功能

问题描述 投票:0回答:1

我想创建触发器来执行功能以截断本地数据库表并插入新数据。在外部数据库表中插入新行之后,必须开始执行触发器。我已经阅读了很多有关在外部表上创建触发器的信息,但是对我来说,它不起作用。当将新行插入到外部表中时,触发器似乎无法执行功能。似乎触发器无法看到此新行插入事件。我做了什么:

  1. 在我的本地数据库中创建了外部表,我们称其为'foreign_table'。经过测试,我可以读取数据。
  2. 创建用于截断本地表并插入新数据的函数:

CREATE or replace FUNCTION public.reset_insert_table() RETURNS TRIGGER LANGUAGE 'plpgsql' SET search_path=public AS $BODY$ BEGIN create temporary table temporary_table_tmp as select * from public.table1; TRUNCATE TABLE public.table2; insert into table2 select * from temporary_table_tmp; DROP table temporary_table_tmp; END; $BODY$;

  1. 已创建触发器以启动功能'reset_insert_table()'

CREATE TRIGGER local_table_update AFTER INSERT ON 'foreign_table' FOR EACH ROW EXECUTE PROCEDURE reset_insert_table();

  1. 进行测试:在外部数据库表'foreign_table'中插入了新行,但是我看不到该表被截断并且没有插入新数据。插入foreign_tale是在外部数据库中完成的。问题还在于测试此触发功能是否起作用,手动执行会产生错误:EXECUTE PROCEDURE reset_insert_table();错误:“执行”或附近的语法错误也尝试了CALL和SELECT。我创建了用于测试的相同函数,但使用“ RETURNS VOID”定义了“ RETURNS TRIGGER”,并且该函数正常工作。

谁能说出我的解决方案为什么不起作用,并且是否在外部表上触发必须看到外部表中发生的事件?

postgresql function database-trigger truncate
1个回答
0
投票

这是对外国表触发器的误解。也许是由于对外国表的误解。

假设您有一个带有表db1的数据库a1,然后连接到另一个数据库db2,并使用CREATE FOREIGN TABLE a2创建一个指向a1外部表

db1。然后,我们可以将a2称为外部表,并且可以将a1称为该外部表的远程表。请注意,外部表是db2中的对象,而远程表是db1中的对象。

[现在您想要的是,只要有人修改a1上的db1,就在a2上执行db2上的触发器。但这不是触发器的工作方式:仅在执行数据修改on a2

时,才会执行a2上定义的触发器。当然,由于a2上的每个数据修改都会导致a1上的数据修改(这反过来可能导致a1上的触发运行)这一事实使情况变得复杂。但事实并非如此。

以这种方式思考:由于a2的定义引用了a1,因此对a2的每个操作都会导致对a1的操作。但是a1db1并不具有在a2中定义db2的最模糊的想法,因此它们没有机会向其传播更改。

您正在寻找的是logical replication,它可以将一个数据库上的所有更改复制到另一个数据库上。然后,您可以在复制的表上定义一个(副本)触发器。

© www.soinside.com 2019 - 2024. All rights reserved.