我有许多使用 Postgres“分区”功能的表。我想在每个表上定义一个通用的 BEFORE INSERT OF 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
但是“新”记录在 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;
但这也不起作用,因为缓存了对临时表的引用:为什么在访问 PL/PgSQL 函数中的临时表时出现“与 OID ##### 的关系不存在”错误?
我正在使用 Postgres 8.2,无法更改为任何其他版本。
编辑:
正如@alvherre 指出的那样,这可能可以在 Postgres 8.4 中使用 EXECUTE ... USING 语法来完成。请参阅http://wiki.postgresql.org/wiki/PL/pgSQL_Dynamic_Triggers中的示例