Ho un numero di tabelle che utilizzano la funzione "Partizionamento" di Postgres. Voglio definire un trigger BEFORE INSERT OF ROW comune su ogni tabella che 1) creerà dinamicamente la partizione se l'inserto si verifica contro la tabella padre e 2) rieseguire l'inserto contro la partizione.Inserimento NEW. * Da un trigger generico utilizzando EXECUTE in PL/pgsql
Qualcosa di simile:
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
Ma il record di "NEW" non è visibile all'interno del SQL EXECUTE. Come posso rendere questo lavoro il più semplice possibile?
In alternativa, posso scorrere in qualche modo i campi del NUOVO record?
ho pensato di utilizzare un temp-tavolo:
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;
Ma anche questo non funziona a causa del riferimento a una cache temp-tavolo: Why do I get "relation with OID ##### does not exist" errors when accessing temporary tables in PL/PgSQL functions?
sto usando Postgres 8.2 e non posso passare a nessuna altra versione.
EDIT:
Come @alvherre sottolineato, questo può essere fatto probabilmente in Postgres 8.4 con la sintassi EXECUTE ... UTILIZZO. Vedere un esempio su http://wiki.postgresql.org/wiki/PL/pgSQL_Dynamic_Triggers
questione connessa successivamente con soluzione per Postgres 8.2: http: // StackOverflow. com/q/7519044/939860 –
@ErwinBrandstetter: la soluzione nella domanda correlata è simile a come ho risolto questo problema nella mia risposta di seguito, ma in questo caso, la funzione deve essere ricompilata ogni volta che una nuova partizione viene aggiunta alla tabella o altrimenti la funzione non sarà a conoscenza delle regole di partizione aggiornate. –