PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Отмяна на транзакция при задействане ГРЕШКА

Няколко проблема с вашата тригерна функция:

  • Използвайте IF EXISTS (...) THEN вместо да брои всички събития. По-бързо, по-лесно. Вижте:

  • Задействаща функция AFTER INSERT OR UPDATE може просто да върне NULL . RETURN NEW е подходящ само за задействания, наречени BEFORE . Ръководството :

  • Небалансирани единични кавички.

  • Както @Pavel обясни , не можете да контролирате транзакции от plpgsql функция. Всяко необработено изключение принуждава цялата ви транзакция да бъде върната автоматично. Така че просто премахнете EXCEPTION блокирай.

Вашият хипотетичен тригер е пренаписан:

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;

A BEFORE задействането има повече смисъл.

Но a UNIQUE INDEX ON ("Room_Name", "Date") би направил същото, по-ефективно. След това всеки ред в нарушение предизвиква изключение за дублиран ключ и връща обратно транзакцията (освен ако не бъде уловен и обработен). В съвременния Postgres можете алтернативно да пропуснете или отклоните такъв INSERT опити с INSERT ... ON CONFLICT ... . Вижте:

Разширено използване:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да избегнем PostgreSQL Cloud Vendor Lock-in

  2. Как е възможно SQL заявката и ActiveRecord.find_by_sql да връщат различни резултати?

  3. postgresql:Защо трябва да посочвам -h localhost, когато изпълнявам psql?

  4. Прозоречна функция на PostgreSQL:дял чрез сравнение

  5. Как да напиша рамка с данни в таблицата на Postgres, без да използвам SQLAlchemy двигател?