Ich habe eine Reihe von Tabellen, die die Postgres "Partitionierung" -Funktion verwenden. Ich möchte einen gemeinsamen BEFORE INSERT OF ROW-Trigger für jede Tabelle definieren, der 1) die Partition dynamisch erstellt, wenn die Einfügung für die Elterntabelle auftritt, und 2) die Einfügung für die Partition erneut ausführt.Einfügen von NEW. * Von einem generischen Trigger mit EXECUTE in PL/pgsql
Etwas wie:
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
Aber die "NEW" Aufzeichnung ist innerhalb der EXECUTE SQL nicht sichtbar. Wie kann ich das so einfach wie möglich machen?
Als Alternative, kann ich irgendwie über die Felder im NEW-Datensatz iterieren?
Ich habe daran gedacht, mit einer temp-Tabelle:
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;
Aber dies auch zu einer temp-Tabelle, da die im Cache gespeicherten Referenz nicht funktioniert: Why do I get "relation with OID ##### does not exist" errors when accessing temporary tables in PL/PgSQL functions?
Ich bin mit Postgres 8.2 und ich kann zu keiner anderen Version wechseln.
EDIT:
Wie @alvherre darauf hingewiesen, kann dies wahrscheinlich in Postgres 8.4 mit der EXECUTE ... weiter verwendet Syntax erfolgen. Ein Beispiel finden Sie unter http://wiki.postgresql.org/wiki/PL/pgSQL_Dynamic_Triggers
Verwandte später Frage mit Lösung für Postgres 8.2: http: // Stackoverflow. com/q/7519044/939860 –
@ErwinBrandstetter: Ihre Lösung in der verwandten Frage ist ähnlich, wie ich dieses Problem in meiner Antwort unten gelöst habe, aber in diesem Fall muss die Funktion jedes Mal neu kompiliert werden, wenn eine neue Partition der Tabelle hinzugefügt wird Andernfalls wird die Funktion die aktualisierten Partitionsregeln nicht kennen. –