Function 使用触发器检查每个值是否已超过PostgreSQL中的限制,并发出通知
我想在这里得到的是哪个科目已经有4个教室,如果超过了,请发出通知并返回null,然后开始工作。但当我插入其他主题“2”时,代码引起了同样的注意,但我这个主题只有1个classrom。我知道我使用的是“Function 使用触发器检查每个值是否已超过PostgreSQL中的限制,并发出通知,function,postgresql,triggers,Function,Postgresql,Triggers,我想在这里得到的是哪个科目已经有4个教室,如果超过了,请发出通知并返回null,然后开始工作。但当我插入其他主题“2”时,代码引起了同样的注意,但我这个主题只有1个classrom。我知道我使用的是“HAVING COUNT(cod_教室)=4”,而代码只得到科目已经有4个教室的内容。我试着只使用这个:“选择不同的cod\u主题,COUNT(cod\u教室)作为cod\u主题组中的CountOf,按cod\u主题”但我不知道如何检查更多值 我希望你们都明白我想要什么,我已经尽了最大的努力了 CR
HAVING COUNT(cod_教室)=4
”,而代码只得到科目已经有4个教室的内容。我试着只使用这个:“选择不同的cod\u主题,COUNT(cod\u教室)作为cod\u主题组中的CountOf,按cod\u主题
”但我不知道如何检查更多值
我希望你们都明白我想要什么,我已经尽了最大的努力了
CREATE OR REPLACE FUNCTION quantas()
RETURNS trigger AS
$BODY$declare qtd record;
begin
SELECT * INTO qtd FROM (SELECT DISTINCT cod_subject,COUNT(cod_classroom) AS CountOf FROM registration_subject
GROUP BY cod_subject HAVING COUNT(cod_classroom) = 4) AS total;
if found then
raise notice 'This subject has already 4 classroom';
return null;
end if;
end;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION qtd()
OWNER TO postgres;
除了Craig在评论中提到的问题(需要锁定独占模式),我认为您还有一些其他问题 你的问题就是这样,对我来说没有多大意义
SELECT * INTO qtd
FROM (SELECT DISTINCT cod_subject,COUNT(cod_classroom) AS CountOf
FROM registration_subject
GROUP BY cod_subject HAVING COUNT(cod_classroom) = 4) AS total;
我不认为这是一种非常有用的查询方式。事实上,只要任何科目有4个教室,它就相当有帮助地拒绝了所有插入
相反,我建议:
PERFORM count(cod_classroom)
FROM registration_subject
WHERE cod_subject = NEW.subject
HAVING count(*) >= 4;
PERFORM
在plpgsql中用于不关心使用结果的情况。在这里,你只关心它是否被找到。第二,如果出现错误,允许错误插入,您仍然会阻止后续插入。如果任何科目正好有四个课室,您的旧代码将阻止插入所有科目,但5个课室是可以的,这也不是您想要的。如果不添加适当的LOCK
语句,此函数容易出现争用条件,这意味着它将在并发删除时错误地拒绝合法更改,并错误地允许多次插入。您必须在独占模式下锁定注册\u主题
表,以获得可靠的结果。采取选择。。。对于共享
行锁不足以防止并发插入。