Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

321
Vistas
Postgres: ignorar los disparadores DELETE para eliminaciones en cascada

Estoy tratando de implementar una relación de personas con direcciones de correo electrónico donde una persona debe tener al menos una dirección de correo electrónico en todo momento. Las tablas se ven así:

 CREATE TABLE persons ( id serial PRIMARY KEY, name text NOT NULL ); CREATE TABLE email_addresses ( id serial PRIMARY KEY, person_id integer REFERENCES persons (id) ON DELETE CASCADE ON UPDATE CASCADE, email_address text NOT NULL );

Para implementar la restricción de que una persona debe tener al menos una dirección de correo electrónico, pensé en usar disparadores. Uno de los desencadenantes necesarios para satisfacer la restricción es un desencadenante BEFORE DELETE en la tabla email_addresses que genera un error si DELETE eliminaría la última dirección de correo electrónico de una persona:

 CREATE FUNCTION email_addresses_delete_trigger() RETURNS trigger AS $$ DECLARE num_email_addresses integer; BEGIN num_email_addresses := (SELECT count(*) FROM email_addresses WHERE person_id = OLD.person_id); IF num_email_addresses < 2 THEN RAISE EXCEPTION 'A person must have at least one email address'; END IF; RETURN OLD; END; $$ LANGUAGE plpgsql; CREATE TRIGGER email_addresses_delete_trigger BEFORE DELETE ON email_addresses FOR EACH ROW EXECUTE FUNCTION email_addresses_delete_trigger();

Este activador hace lo que debe hacer, sin embargo, evita que se elimine a una persona de la tabla de persons . Por ejemplo:

 mydb=# DELETE FROM persons WHERE id = 1; ERROR: A person must have at least one email address CONTEXT: PL/pgSQL function email_addresses_delete_trigger() line 7 at RAISE SQL statement "DELETE FROM ONLY "public"."email_addresses" WHERE $1 OPERATOR(pg_catalog.=) "person_id""

Si elimino a una persona, también quiero que se eliminen todas sus direcciones de correo electrónico, por lo que no me importa si la restricción representada por el activador se mantiene durante el proceso de eliminación en cascada. ¿Hay alguna forma de "ignorar" este disparador cuando se elimina a una persona? ¿O hay alguna otra forma en que tendría que eliminar a una persona?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Mi recomendación es cambiar el modelo de datos para que tenga una restricción de clave externa no anulable de persons a direcciones de email_addresses electrónico que se vincule a una de las direcciones de la persona. Luego, su requisito se cumple automáticamente y no necesita un disparador.

Eso hará que algunas cosas, como eliminar una dirección de correo electrónico, sean más complicadas, pero no tiene que depender de un activador de integridad, que siempre está sujeto a condiciones de carrera .

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda