sql >> Base de Datos >  >> RDS >> PostgreSQL

Transacción de reversión en ERROR de activación

Un par de problemas con la función de activación:

  • Use IF EXISTS (...) THEN en lugar de contar todas las ocurrencias. Más rápido, más simple. Ver:

  • Una función desencadenante AFTER INSERT OR UPDATE simplemente puede devolver NULL . RETURN NEW solo es relevante para activadores llamados BEFORE . El manual :

  • Comilla simple no balanceada.

  • Como explicó @Pavel , no puede controlar las transacciones desde dentro de una función plpgsql. Cualquier excepción no controlada obliga a que toda la transacción se revierta automáticamente. Entonces, simplemente elimine la EXCEPTION bloquear.

Tu disparador hipotético reescrito:

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 disparador tiene más sentido.

Pero a UNIQUE INDEX ON ("Room_Name", "Date") haría lo mismo, más eficientemente. Luego, cualquier fila en violación genera una excepción de clave duplicada y revierte la transacción (a menos que se detecte y maneje). En Postgres moderno, alternativamente puede omitir o desviar tales INSERT intentos con INSERT ... ON CONFLICT ... . Ver:

Uso avanzado: