PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Restauration de la transaction lors d'une erreur de déclenchement

Quelques problèmes avec votre fonction de déclenchement :

  • Utilisez IF EXISTS (...) THEN au lieu de compter toutes les occurrences. Plus rapide, plus simple. Voir :

  • Une fonction déclencheur AFTER INSERT OR UPDATE peut simplement renvoyer NULL . RETURN NEW n'est pertinent que pour les déclencheurs appelés BEFORE . Le manuel :

  • Apostrophe déséquilibrée.

  • Comme @Pavel expliqué , vous ne pouvez pas contrôler les transactions depuis une fonction plpgsql. Toute exception non gérée force l'annulation automatique de l'intégralité de votre transaction. Donc, supprimez simplement l'EXCEPTION bloquer.

Votre déclencheur hypothétique réécrit :

CREATE OR REPLACE FUNCTION check_room()
  RETURNS TRIGGER AS
$func$
BEGIN
   IF EXISTS (
         SELECT FROM "Sesion"    -- are you sure it's not "Session"?
         WHERE  "Room_Name" = NEW."Room_Name"
         AND    "Date" = NEW."Date") THEN
     RAISE EXCEPTION 'The room is rented at that date';
   END IF;
   RETURN NULL;
END
$func$  LANGUAGE plpgsql;

Un BEFORE le déclencheur a plus de sens.

Mais un UNIQUE INDEX ON ("Room_Name", "Date") ferait la même chose, plus efficacement. Ensuite, toute ligne en violation lève une exception de clé en double et annule la transaction (sauf si elle est interceptée et gérée). Dans Postgres moderne, vous pouvez également ignorer ou détourner ces INSERT tentatives avec INSERT ... ON CONFLICT ... . Voir :

Utilisation avancée :