2009-05-01 19 views
5

¿Es posible evitar la eliminación de la primera fila en la tabla en el lado de PostgreSQL?Cómo evitar la eliminación de la primera fila en la tabla (PostgreSQL)?

Tengo una tabla de categorías y deseo evitar la eliminación de la categoría predeterminada, ya que podría romper la aplicación. Por supuesto, podría hacerlo fácilmente en el código de la aplicación, pero sería mucho mejor hacerlo en la base de datos.

Creo que tiene algo que ver con las reglas sobre la declaración de eliminación, pero no pude encontrar nada remotamente cercano a mi problema en la documentación.

Respuesta

6

La mejor manera que veo de lograr esto es mediante la creación de un desencadenador de eliminación en esta tabla. Básicamente, tendrá que escribir un procedimiento almacenado para asegurarse de que esta categoría 'predeterminada' siempre existirá, y luego aplicarla usando un evento desencadenador ON DELETE en esta tabla. Una buena forma de hacerlo es crear un disparador por fila que garantice que en los eventos DELETE la fila de la categoría 'predeterminada' nunca se borre.

Por favor, echa un vistazo a la documentación de PostgreSQL sobre disparadores y procedimientos almacenados:

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

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

También hay ejemplos valiosos en este wiki:

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

9

Quiere definir un ANTES DE ELIMINAR trigger en la tabla. Cuando intente eliminar la fila (ya sea por PK o tenga una columna booleana "proteger" por separado), RAISE es una excepción.

No estoy familiarizado con la sintaxis de PostgreSQL, pero it looks like esta es la forma en que lo harías:

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

Gracias por su respuesta. Tanto usted como Macalendas diste respuestas útiles por lo que fue difícil elegir la respuesta "aceptada", pero decidí dársela a Macalendas para alentar a los nuevos usuarios a participar en este increíble sitio. ¡Gracias! –

+0

No hay problema y me alegro de poder ayudar. También cerré un desajuste citar en una etiqueta para que los enlaces funcionen correctamente ahora. –

9

Tenías razón al pensar en el sistema de reglas. Here es un enlace a un ejemplo que coincide con su problema. Es incluso más sencillo que los factores desencadenantes:

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; 

Algunas respuestas se pierda un punto: también la actualización de la fila protegida tiene que ser restringido. De lo contrario, primero se puede actualizar la fila protegida de modo que ya no cumpla el criterio de eliminación prohibida, y luego se puede eliminar la fila actualizada ya que ya no está protegida.

+0

no estoy seguro de por qué esta respuesta no está recibiendo más amor, pero las reglas de protección son increíbles!: +1: –

0

Tenga en cuenta cómo funcionan los desencadenantes. Se dispararán por cada fila que elimine su declaración de eliminación. Esto no significa que no deba usar desencadenantes solo tenga esto en cuenta y, lo que es más importante, pruebe sus escenarios de uso y asegúrese de que el desempeño cumpla con los requisitos.

¿Debo usar una regla o un disparador?

"Para las cosas que pueden implementarse por ambos, lo mejor depende del uso de la base de datos. Se dispara un desencadenante para una fila afectada una vez. Una regla manipula la consulta o genera una consulta adicional. Por lo tanto, si se afectan muchas filas en una declaración, una regla que emite un comando adicional es más probable que sea más rápida que la activación de cada fila y debe ejecutar sus operaciones muchas veces.Sin embargo, el enfoque de disparo es conceptualmente mucho más simple que el enfoque de la regla, y es más fácil para los principiantes para hacerlo bien."

Consulte la documentación para más detalles.
http://www.postgresql.org/docs/8.3/interactive/rules-triggers.html

Cuestiones relacionadas