Триггер в PostgreSQL - PullRequest
       15

Триггер в PostgreSQL

1 голос
/ 01 февраля 2011

У меня есть таблица "Candidates" с id (первичный ключ) и application_counter
и таблица "Applications" с внешним ключом (candidate_id). Я хочу, чтобы application_counter изменялся каждый раз, когда приложение добавляется или удаляется (или изменяется путем изменения candidate_id).

Все, что я могу сделать, это написать:

CREATE TRIGGER myTrigger AFTER INSERT OR DELETE OR UPDATE
ON "Applications" FOR EACH ROW
EXECUTE PROCEDURE funcname ( arguments )

И вопрос в том, как мне написать этот триггер?

Сводка со страницы http://www.postgresql.org/docs/8.1/interactive/sql-createtrigger.html

CREATE TRIGGER name { BEFORE | AFTER } { event [ OR ... ] }
ON table [ FOR [ EACH ] { ROW | STATEMENT } ]
EXECUTE PROCEDURE funcname ( arguments )

Ответы [ 2 ]

3 голосов
/ 01 февраля 2011

Я бы использовал представление INNER JOIN двух таблиц и посчитал бы строки в таблице applications.(См. COUNT().) Триггеры могут быть отключены;это представление всегда даст вам правильный ответ.

(Позже ...)

Я понимаю, что вы хотите ограничить количество строк кандидата в "приложениях" таблицы до 3 или меньше.В этом случае, я думаю, лучше использовать ограничение CHECK() для «приложений», а не комбинацию триггера для «приложений» и ограничение CHECK() для «кандидатов».

Чтобы сделать это в PostgreSQL, вы должны использовать функцию и вызывать функцию из CHECK().(Насколько я знаю. Вы все еще не можете выполнить произвольные операторы SELECT в ограничениях CHECK(), верно?) Итак, вы бы создали эту функцию,

CREATE FUNCTION num_applications(cand_id integer)
  RETURNS integer AS
$BODY$ 

  DECLARE 
    n integer; 
  BEGIN 
    select count(*) 
    into n 
    from applications
    where (candidate_id = cand_id);

    return n; 
  END; 
$BODY$ 
LANGUAGE plpgsql;

, а затем вы быдобавьте ограничение CHECK () к таблице 'application'.

ALTER TABLE applications
  ADD CONSTRAINT max_of_three CHECK (num_applications(candidate_id) < 3);

"<3", поскольку ограничение <code>CHECK() оценивается перед добавлением строки.Вероятно, стоит проверить, как это происходит с отложенными ограничениями.Если у меня будет время, я сделаю это.

3 голосов
/ 01 февраля 2011
CREATE TRIGGER myname AFTER INSERT, DELETE OR UPDATE 
ON table applications
EXECUTE PROCEDURE myfunc();

CREATE FUNCTION myfunc() RETURNS TRIGGER AS 
BEGIN
    IF TG_OP != 'DELETE' THEN
        update candicate set application_count = application_count + 1 where id = new.candidate_id;
    END IF;
    IF TG_OP != 'INSERT' THEN
        update candicate set application_count = application_count + 1 where id = old.candidate_id;
    END IF;
END;

Надеюсь, вы поняли идею ... теперь работает и с обновленными кандидатами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...