我的表格"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 )
答案 0 :(得分:3)
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;
我希望你能得到这个想法......现在也可以使用更新的candidate_id。
答案 1 :(得分:3)
我将使用两个表的视图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()约束。
ALTER TABLE applications
ADD CONSTRAINT max_of_three CHECK (num_applications(candidate_id) < 3);
“&lt; 3”,因为在添加行之前评估CHECK()
约束。可能值得测试看看它如何与延迟约束一起运行。如果我以后有时间,我会这样做。