2015-04-16 16 views
8

Ho un trigger, ma ho bisogno di associarmi a tutte le tabelle dei miei postgres. C'è un comando come questo sotto?Come creare trigger per tutte le tabelle in postgresql?

CREATE TRIGGER delete_data_alldb 
BEFORE DELETE 
ON ALL DATABASE 
FOR EACH ROW 
EXECUTE PROCEDURE delete_data(); 
+0

No, non è disponibile alcun supporto per i trigger del database. Perché vorresti fare comunque questa cosa in particolare? –

+0

Ho bisogno di registrare le azioni del database da sincronizzare con lo smartphone. Quindi eseguirò questo trigger table per tabella. Grazie per l'aiuto. –

+0

@EduardoRafaelCorreadeSouza So che sono trascorsi un paio di giorni da quando hai fatto quella domanda e probabilmente l'hai fatto a mano. Ma controlla la mia risposta. Se ti ha fatto imparare qualcosa di utile che ti può aiutare in futuro con un compito simile, sarebbe gentile da parte tua considerare di accettare la mia risposta. –

risposta

8

Beh c'è nessuna creazione di attivazione a livello di database, ma per tutte queste bulk-admin-operazioni è possibile utilizzare le tabelle di sistema di PostgreSQL per generare query per voi invece di scrivere a mano. In questo caso è possibile eseguire:

SELECT 
    'CREATE TRIGGER ' 
    || tab_name 
    || ' BEFORE DELETE ON ALL DATABASE FOR EACH ROW EXECUTE PROCEDURE delete_data();' AS trigger_creation_query 
FROM (
    SELECT 
     quote_ident(table_schema) || '.' || quote_ident(table_name) as tab_name 
    FROM 
     information_schema.tables 
    WHERE 
     table_schema NOT IN ('pg_catalog', 'information_schema') 
     AND table_schema NOT LIKE 'pg_toast%' 
) tablist; 

Questo ti porterà insieme di stringhe che sono i comandi SQL come:

CREATE TRIGGER schema1.table1 BEFORE DELETE ON ALL DATABASE FOR EACH ROW EXECUTE PROCEDURE delete_data(); 
CREATE TRIGGER schema1.table2 BEFORE DELETE ON ALL DATABASE FOR EACH ROW EXECUTE PROCEDURE delete_data(); 
CREATE TRIGGER schema1.table3 BEFORE DELETE ON ALL DATABASE FOR EACH ROW EXECUTE PROCEDURE delete_data(); 
CREATE TRIGGER schema2.table1 BEFORE DELETE ON ALL DATABASE FOR EACH ROW EXECUTE PROCEDURE delete_data(); 
CREATE TRIGGER schema2."TABLE2" BEFORE DELETE ON ALL DATABASE FOR EACH ROW EXECUTE PROCEDURE delete_data(); 
... 
etc 

Hai solo bisogno di correre in una volta (o per psql o pgAdmin) .

Ora qualche spiegazione:

  • I selezionare i nomi delle tabelle nel mio database utilizzando information_schema.tables tabella di sistema. Dato che ci sono dati letteralmente su tutte le tabelle, ricordati di escludere gli schemi pg_catalog e information_schema e le tabelle dei toast dal tuo select.
  • Uso la funzione quote_ident(text) che inserirà la stringa all'interno dei segni di doppia quota ("") se necessario (ad esempio, i nomi con spazi o lettere maiuscole richiedono quello).
  • Quando ho un elenco di nomi di tabelle, li concateno con alcune stringhe statiche per ottenere i miei comandi SQL.
  • Scrivo questo comando utilizzando la sottoquestazione perché voglio che tu abbia un'idea migliore di cosa sta succedendo qui. È possibile scrivere una singola query inserendo quote_ident(table_schema) || '.' || quote_ident(table_name) al posto di tab_name.
+1

Ho ottenuto 'subquery in FROM deve avere un alias', quindi aggiunto') AS inner_select; 'fino alla fine e ha funzionato. –

+0

@IanVaughan grazie al 100% giusto! Ho corretto la mia risposta. –

Problemi correlati