在同一事件触发之前和之后?填充子表PostgreSQL
形势 我在PostgreSQL 9.5中有一个数据库,用于按时间存储对象位置 我有一个名为“position”的主表,其中包含列(仅相关):在同一事件触发之前和之后?填充子表PostgreSQL,postgresql,inheritance,triggers,partitioning,return-type,Postgresql,Inheritance,Triggers,Partitioning,Return Type,形势 我在PostgreSQL 9.5中有一个数据库,用于按时间存储对象位置 我有一个名为“position”的主表,其中包含列(仅相关): position\u id position\u时间戳 object\u id 它在对象_id上被划分为100个子表,条件是: CREATE TABLE position_object_id_00 ( CHECK object_id%100 = 0 ) INHERITS ( position ); 对其他孩子来说也是如此。我使用模关系进行分区,以使
position\u id
position\u时间戳
object\u id
CREATE TABLE position_object_id_00
( CHECK object_id%100 = 0 )
INHERITS ( position );
对其他孩子来说也是如此。我使用模关系进行分区,以使对象均匀分布。
每个子项都在位置id和对象id
上建立索引(两个不同的索引)
在子对象上重定向插入的触发器是:
CREATE TRIGGER insert_position_trigger
BEFORE INSERT ON position
FOR EACH ROW EXECUTE PROCEDURE insert_position();
并且过程insert\u position()
查找要插入数据的正确子表,插入它,然后返回新对象:
CREATE OR REPLACE FUNCTION insert_position() RETURNS TRIGGER AS $insert_position$
DECLARE
BEGIN
--Look for child table
[...]
--Insert data in right child table
[...]
RETURN NEW;
END;
$insert_position$ LANGUAGE plpgsql;
我有一个汇总表object\u last\u known\u position
,其列与触发器更新的列相同:
CREATE TRIGGER update_object_last_known_position
AFTER INSERT OR UPDATE ON position
FOR EACH ROW
EXECUTE PROCEDURE update_object_last_known_position();
过程update\u object\u last\u known\u position()
基本上检查position\u时间戳是否较新,然后删除旧条目并使用INSERT或update查询(new)上传递的数据创建新条目
问题
所以这两个触发器对同一事件做出反应:插入位置,一个在前面,另一个在后面
返回new forinsert\u position()
允许我在触发器中使用newupdate\u object\u last\u known\u position()
,这是绝对必要的。但这样做,它也会在主表位置插入数据。所以我的数据现在被复制了
我试着将这两个触发器放在前面,如果我这样插入数据,它们都会在插入数据时执行,但是如果我从过程insert\u position()
中删除“return new”,则不会执行update\u object\u last\u known\u position()
我遇到了这个问题,在插入数据时,我没有找到一种方法在不填充主表位置的情况下执行这两个触发器
因此,如果您有任何想法,我将非常感谢:)
谢谢你的帮助
编辑
解决方案
多亏了这个答案
我“合并”了两个触发器:insert\u position()
now直接调用update\u object\u last\u known\u position
。为此,我将update\u object\u last\u known\u position
修改为带有参数的存储过程。该参数是刚刚创建的positioninsert\u position()
的id,因此我可以找到它并检索信息。
(在另一个触发器中调用update\u object\u last\u known\u position
表示我们不能再使用NEW
)
显然,insert\u position()
的返回类型现在是NULL
,一切正常:)如果我理解正确,您正在尝试:
停止insert,并将其替换为另一个表中的insert(由触发器确定)
更新摘要表(delete
/insert
)以指向新行
你的问题是1阻止2发生?这是合乎逻辑的,因为您已经停止了插入,所以您也停止了对插入的任何处理
因此,要解决这个问题,您有两个选项(选项1和2类似)
从insert\u position()
调用update\u object\u last\u known\u position()
,并且只有一个触发器
为insert\u position()
和update\u object\u last\u known\u position()
创建一个包装方法,并且只有一个触发器
将update\u object\u last\u known\u position()
的触发器放在insert\u position()
可能插入的所有表上
如果我理解正确,您正在尝试:
停止insert,并将其替换为另一个表中的insert(由触发器确定)
更新摘要表(delete
/insert
)以指向新行
你的问题是1阻止2发生?这是合乎逻辑的,因为您已经停止了插入,所以您也停止了对插入的任何处理
因此,要解决这个问题,您有两个选项(选项1和2类似)
从insert\u position()
调用update\u object\u last\u known\u position()
,并且只有一个触发器
为insert\u position()
和update\u object\u last\u known\u position()
创建一个包装方法,并且只有一个触发器
将update\u object\u last\u known\u position()
的触发器放在insert\u position()
可能插入的所有表上
拥有更完整的代码可能会有所帮助,但听起来像是在更新\u object\u last\u known\u position()
中插入新行,同时插入新行(以便触发触发器)。您能不能不在update\u object\u last\u known\u position()
中插入行主表中插入的行不是由于update\u object\u last\u known\u position()
而是由于insert\u position()
。因为它是一个返回新的触发器,所以我认为它不会“停止”插入。我需要在object\u last\u known\u position
中插入一行,这是设计的一部分:我需要存储最后一个位置,以便在请求时具有更好的性能。这将有助于获得更完整的代码,但听起来像是在update\u object\u last\u known\u position()
中插入新行以及插入新行(为了触发触发器)。您可以不在update\u object\u last\u known\u position()
中插入行吗?主表中插入的行不是由于update\u object\u last\u known\u position()
而是由于insert\u position()插入,我想。我需要在object\u last\u known\u位置插入一行