在同一事件触发之前和之后?填充子表PostgreSQL

在同一事件触发之前和之后?填充子表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 ); 对其他孩子来说也是如此。我使用模关系进行分区,以使

形势

我在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 );
对其他孩子来说也是如此。我使用模关系进行分区,以使对象均匀分布。 每个子项都在
位置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 for
insert\u position()
允许我在触发器中使用new
update\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
修改为带有参数的存储过程。该参数是刚刚创建的position
insert\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位置插入一行