postgresql - 记录 "new"尚未分配

标签 postgresql function triggers plpgsql table-partitioning

我正在尝试实现表分区,我在 PostgreSQL 中有以下代码(来自 https://www.postgresql.org/docs/9.6/ddl-partitioning.html)

CREATE or replace FUNCTION child_tables.func_inventory_movement_insert_trigger()
    RETURNS trigger 
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$BEGIN

   IF  ( NEW.report_date >=  '2019-04-01 ' AND
         NEW.report_date <  '2019-05-01 ' ) THEN
        INSERT INTO child_tables.inventory_movement_y2019m03 VALUES (NEW.*);

    ELSIF ( NEW.report_date >=  '2019-06-01 ' AND
            NEW.report_date <  '2019-07-01 ' ) THEN

        INSERT INTO child_tables.inventory_movement_y2019m04 VALUES (NEW.*);

    ELSE
        RAISE EXCEPTION 
        ' out of range exception.  Fix the child_tables.func_inventory_movement_insert_trigger() function. ';
    END IF;
    RETURN NULL;
END;
$BODY$;

触发函数:

CREATE TRIGGER im_partition_trigger
BEFORE INSERT OR DELETE OR UPDATE 
ON core.inventory_movement
FOR EACH ROW
EXECUTE PROCEDURE child_tables.func_inventory_movement_insert_trigger();

在上述触发器之后或之前都进行了尝试。

ERROR: record "new" is not assigned yet
DETAIL: The tuple structure of a not-yet-assigned record is indeterminate.

仅供引用,相同的代码适用于另一个表。

有什么建议吗?

最佳答案

你的触发器已定义

BEFORE INSERT OR DELETE OR UPDATE 

但是 NEW 没有为 DELETE 定义。所以你的触发函数注定会失败。

要么为INSERT/UPDATE/DELETE 编写单独的触发器函数和触发器(推荐)。显示的触发器函数仅处理 INSERT。所以这个触发器是有意义的:

CREATE TRIGGER im_partition_trigger
BEFORE INSERT    -- !!
ON core.inventory_movement
FOR EACH ROW EXECUTE PROCEDURE child_tables.func_inventory_movement_insert_trigger();

或者将所有对 OLDNEW 的调用嵌套在 IFCASE 结构中的组合触发器函数中,检查对于 TG_OP .

Code examples in many related questions.

也就是说,要实现表分区,我更愿意使用 declarative partitioning在 Postgres 10 或更高版本中。理想情况下,使用即将推出的 Postgres 12,它为分区带来了重大改进。

此外,在 Postgres 11 或更高版本中,触发器使用固定语法:

...
FOR EACH ROW EXECUTE FUNCTION child_tables.func_inventory_movement_insert_trigger();

这是一个函数,而不是一个“过程”。

关于postgresql - 记录 "new"尚未分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58020214/

相关文章:

node.js - 如何回滚一天?

python - GeoDjango touches 功能很慢

json - PostgreSQL单列表转JSON数组

c++ - 通过函数传递引用?

php - Objective-C 默认参数值

wpf - 有没有办法使禁用的按钮上的图像去饱和?

sql - 使用 dblink 无法在 2 个数据库之间更新

python - 如何使用用户输入来调用 Python 中的函数?

sql-server - 插入/更新/删除使用单个触发器还是多个触发器更好?

java - 用于获取插入值的 Cassandra 示例触发代码