Domanda

È possibile impedire la cancellazione della prima riga nella tabella sul lato PostgreSQL?

Ho una tabella delle categorie e desidero impedire la cancellazione della categoria predefinita in quanto potrebbe interrompere l'applicazione. Ovviamente 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 delete, ma non sono riuscito a trovare nulla di remoto vicino al mio problema nella documentazione.

È stato utile?

Soluzione

Il modo migliore per vedere ciò è creare un trigger di eliminazione su questa tabella. Fondamentalmente, dovrai scrivere una procedura memorizzata per assicurarti che questa categoria "predefinita" esista sempre, quindi applicarla utilizzando un evento ON DELETE su questa tabella. Un buon modo per farlo è creare un trigger per riga che garantirà che negli eventi DELETE la riga della categoria "predefinita" non verrà mai eliminata.

Consulta la documentazione di PostgreSQL sui trigger e le procedure memorizzate:

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

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

Ci sono anche esempi preziosi in questo wiki:

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

Altri suggerimenti

Avevi ragione a pensare al sistema di regole. Qui è un collegamento a un esempio che corrisponde al tuo problema. È ancora più semplice dei 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 mancano un punto: anche l'aggiornamento della riga protetta deve essere limitato. In caso contrario, è possibile innanzitutto aggiornare la riga protetta in modo tale che non soddisfi più il criterio di eliminazione vietata, quindi è possibile eliminare la riga aggiornata poiché non è più protetta.

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

Non ho familiarità con la sintassi PostgreSQL, ma sembra ecco 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();

Potresti avere una riga in un'altra tabella (chiamata default) che fa riferimento alla categoria predefinita. Il vincolo FK non consentirebbe la cancellazione della categoria predefinita.

Tieni presente come funzionano i trigger. Si spengono per ogni riga che verrà eliminata dall'istruzione di eliminazione. Questo non significa che non dovresti usare i trigger, tienilo a mente e, soprattutto, testa i tuoi scenari di utilizzo e assicurati che le prestazioni soddisfino i requisiti.

Devo usare una regola o un trigger?

Dai documenti ufficiali: " Per le cose che possono essere implementate da entrambi, la cosa migliore dipende dall'uso del database. Viene attivato un trigger per ogni riga interessata una volta. Una regola manipola la query o genera una query aggiuntiva. Pertanto, se più righe sono interessate in una sola istruzione, è probabile che una regola che emette un comando aggiuntivo sia più veloce di un trigger chiamato per ogni singola riga e che deve eseguire le sue operazioni più volte. Tuttavia, l'approccio innescato è concettualmente molto più semplice dell'approccio basato sulle regole ed è più facile per i principianti avere ragione. & Quot;

Vedi i documenti per i dettagli.
http://www.postgresql.org/docs/8.3/interactive/ regole-triggers.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top