запись "новая" еще не назначена - PullRequest
0 голосов
/ 20 сентября 2019

Я пытаюсь реализовать разбиение таблицы, и у меня есть следующий код в 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.

К вашему сведению, тот же код работает для другой таблицы.

Есть предложения?

1 Ответ

2 голосов
/ 20 сентября 2019

Ваш триггер определен

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();

Или вкладывать все вызовы OLD и NEW в комбинированную функцию триггера в конструкциях IF или CASE, проверяя на TG_OP.

Примеры кода во многих смежных вопросах.

Тем не менее, реализовать разбиение таблицы Я быгораздо лучше использовать декларативное разбиение в Postgres 10 или новее.В идеале, используйте предстоящий Postgres 12, который принесет значительные улучшения для разбиения.

Кроме того, в Postgres 11 или более поздних версиях лучше использовать фиксированный синтаксис для триггеров:

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

Это функция,не "процедура".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...