У меня есть несколько таблиц, в которых используется функция "Разметка" Postgres. Я хочу определить общий триггер ПЕРЕД ВСТРОЕНЫ ROW для каждой таблицы, который будет: 1) динамически создавать раздел, если вставка происходит против родительской таблицы, и 2) повторно выполнить вставку против раздела.
Что-то вроде:
CREATE OR REPLACE FUNCTION partition_insert_redirect( )
RETURNS trigger AS $BODY$
BEGIN
... create the new partition and set up the redirect Rules ...
/* Redo the INSERT dynamically. The new RULE will redirect it to the child table */
EXECUTE 'INSERT INTO ' || quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(TG_TABLE_NAME) ||
' SELECT NEW.*'
END
Но запись "NEW" не отображается внутри EXECUTE SQL. Как я могу сделать эту работу максимально простой?
Как альтернатива, могу ли я как-то перебирать поля в NEW-записи?
Я подумал об использовании временной таблицы:
EXECUTE 'CREATE TEMPORARY TABLE new_row (LIKE ' ||
quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(TG_TABLE_NAME) ||
') ON COMMIT DROP';
INSERT INTO new_row SELECT NEW.*;
EXECUTE 'INSERT INTO ' || quote_ident(TG_TABLE_SCHEMA) || '.' || quote_ident(TG_TABLE_NAME) ||
' SELECT * FROM new_row';
DROP TABLE new_row;
Но это также не работает из-за кэшированной ссылки на временную таблицу: Почему я получаю "отношение с OID ##### does не существует" при доступе к временным таблицам в функциях PL/PgSQL?
Я использую Postgres 8.2, и я не могу перейти на другую версию.
EDIT:
Как отметил @alvherre, это, вероятно, можно сделать в Postgres 8.4 с синтаксисом EXECUTE... USING. Пример: http://wiki.postgresql.org/wiki/PL/pgSQL_Dynamic_Triggers