Wstawianie NEW. * Z ogólnego wyzwalacza za pomocą EXECUTE w PL / pgsql
Mam wiele tabel, które używają funkcji „Partycjonowanie” Postgres. Chcę zdefiniować wspólny wyzwalacz BEFORE INSERT OF ROW na każdej tabeli, która 1) dynamicznie utworzy partycję, jeśli wstawka wystąpi w stosunku do tabeli nadrzędnej i 2) ponownie wykona wstawienie względem partycji.
Coś jak:
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
Ale rekord „NOWY” nie jest widoczny w EXECUTE SQL. Jak mogę wykonać tę pracę tak prosto, jak to możliwe?
Alternatywnie, czy mogę jakoś iterować po polach w NOWYM rekordzie?
Myślałem o użyciu tabeli tymczasowej:
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;
Ale to również nie działa z powodu buforowanego odwołania do tabeli tymczasowej:Dlaczego dostaję błędy „relacja z OID ##### nie istnieje” podczas uzyskiwania dostępu do tabel tymczasowych w funkcjach PL / PgSQL?
Używam Postgres 8.2 i nie mogę zmienić na inną wersję.
EDYTOWAĆ:
Jak zauważył @alvherre, można to prawdopodobnie zrobić w Postgresie 8.4 za pomocą składni EXECUTE ... USING. Zobacz przykład nahttp://wiki.postgresql.org/wiki/PL/pgSQL_Dynamic_Triggers