2009-05-01 7 views
5

È possibile impedire la cancellazione della prima riga nella tabella sul lato PostgreSQL?Come evitare la cancellazione della prima riga nella tabella (PostgreSQL)?

Ho una tabella delle categorie e desidero impedire la cancellazione della categoria predefinita in quanto potrebbe interrompere l'applicazione. Naturalmente potrei farlo facilmente nel codice dell'applicazione, ma sarebbe molto meglio farlo nel database.

Penso che abbia qualcosa a che fare con le regole sull'istruzione di eliminazione, ma non ho trovato nulla di lontanamente vicino al mio problema nella documentazione.

risposta

6

Il modo migliore che vedo per farlo è attraverso la creazione di un trigger di eliminazione su questo tavolo. Fondamentalmente, dovrai scrivere una stored procedure per assicurarti che questa categoria 'default' esista sempre e quindi applicarla con un evento ON DELETE su questa tabella. Un buon modo per fare ciò è creare un trigger per riga che garantisca che su eventi DELETE la riga di categoria 'default' non verrà mai cancellata.

Si prega di verificare la documentazione di PostgreSQL sui trigger e stored procedure:

http://www.postgresql.org/docs/8.3/interactive/trigger-definition.html

http://www.postgresql.org/docs/8.3/interactive/plpgsql.html

C'è anche esempi importanti in questo wiki:

http://wiki.postgresql.org/wiki/A_Brief_Real-world_Trigger_Example

9

Si desidera definire PRIMA DELETE trigger sul tavolo. Quando si tenta di eliminare la riga (corrisponde a PK o una colonna booleana "protect" separata), RAISE un'eccezione.

Non ho dimestichezza con la sintassi PostgreSQL, ma it looks like questo è come lo faresti:

CREATE FUNCTION check_del_cat() RETURNS trigger AS $check_del_cat$ 
    BEGIN    
     IF OLD.ID = 1 /*substitute primary key value for your row*/ THEN 
      RAISE EXCEPTION 'cannot delete default category'; 
     END IF; 

    END; 
$check_del_cat$ LANGUAGE plpgsql; 

CREATE TRIGGER check_del_cat BEFORE DELETE ON categories /*table name*/ 
    FOR EACH ROW EXECUTE PROCEDURE check_del_cat(); 
+0

Grazie per la risposta. Sia tu che Macalendas dato risposte utili quindi è stato difficile scegliere la risposta "accettata", ma ho deciso di darlo a Macalendas per incoraggiare i nuovi utenti a partecipare a questo fantastico sito Grazie! –

+0

Nessun problema e felice di aver potuto aiutare. citare in un tag in modo che i collegamenti funzionino correttamente ora. –

9

Avevi ragione a pensare al sistema di regole. Here è un collegamento a un esempio che corrisponde al problema. E 'ancora più semplice rispetto ai trigger:

create rule protect_first_entry_update as 
    on update to your_table 
    where old.id = your_id 
    do instead nothing; 
create rule protect_first_entry_delete as 
    on delete to your_table 
    where old.id = your_id 
    do instead nothing; 

Alcune risposte manca un punto: anche l'aggiornamento della riga protetta deve essere limitato. Altrimenti si può prima aggiornare la riga protetta in modo tale che non soddisfi più il criterio di cancellazione proibita, e quindi si può cancellare la riga aggiornata in quanto non è più protetta.

+0

non si sa perché questa risposta non ottenga più amore ma le regole di protezione sono impressionanti!: +1: –

0

Ricordare come funzionano i trigger. Spareranno per ogni riga eliminata dalla tua istruzione di cancellazione. Ciò non significa che non dovresti usare i trigger, ma tieni questo a mente e, soprattutto, verifica i tuoi scenari di utilizzo e assicurati che le prestazioni soddisfino i requisiti.

Devo utilizzare una regola o un trigger?

Dai documenti ufficiali: "Per le cose che possono essere implementate da entrambi, che è il migliore dipende dall'utilizzo del database.Un trigger viene attivato per ogni riga interessata una volta. Una regola manipola la query o genera un Quindi se molte righe sono interessate in una dichiarazione, è probabile che una regola che emette un comando in più sia più veloce di un trigger chiamato per ogni singola riga e deve eseguire le sue operazioni più volte.Tuttavia, l'approccio grilletto è concettualmente molto più semplice rispetto all'approccio regola, ed è più facile per i principianti di ottenere ragione ".

Vedere la documentazione per i dettagli.
http://www.postgresql.org/docs/8.3/interactive/rules-triggers.html