我的问题是我达到了堆栈极限。消息错误显示“您应该增加max_stack_depth
”,并向我显示用于更新另一列的行。
更新请求后,我遇到此错误(下面的代码)。
我知道我的问题可能看起来像其他问题,但是没有一个可以解释为什么我会遇到此错误。
我想做的很简单,我做了很多次,但是在这里我缺少了一些东西。
我想要:如果表support_fh
上有更新,请扣动触发器。我希望此触发器能够做到:
如果更新请求的新值为section
= 'DISTRIBUTION'
和modulo
= '6'
和fabricant
= 'NEXANS'
和{{ 1}} = capacite
,然后设置12
= diametre
(下面的代码)。
当然,这是'12.5'
所在的行,与更新请求所在的行相同。
还有一点,我知道我应该使用diametre
类型而不是character varying
类型,但是我被要求这样做。
我的触发功能:
integer
我的触发器:
create or replace function maj_diam() returns trigger
as
$$
Declare fab_loc character varying;
Declare section_loc character varying;
Declare capa_loc character varying;
Declare modulo_loc character varying;
BEGIN
Select fabricant into fab_loc from support_fh where id = new.id;
Select section into section_loc from support_fh where id = new.id;
Select capcite into capa_loc from support_fh where id = new.id;
Select modulo into modulo_loc from support_fh where id = new.id;
if fab_loc = 'NEXANS' and section_loc = 'DISTRIBUTION'
and capa_loc = '12' and modulo_loc = '6' then
update support_fh set diametre = '12.2' where id = new.id;
endif;
return new;
end;
$$;
我的更新请求以测试我的触发器:
create trigger maj_diam
After update on support_fh
for each row
execute procedure maj_diam();
我想从中学到东西,所以,如有可能,请向我解释我在这里做错了什么,或者我的方法缺乏见识。
答案 0 :(得分:2)
您会遇到此问题,因为触发器中的更新将再次启动触发器,从而导致无限循环。 max_stack_depth
的值没有足够大的值(并且过分增大该值仍然很危险)。
您应该创建一个BEFORE
触发器,并修改即将插入的NEW
值,而不是您正在做什么:
IF NEW.fab_loc = 'NEXANS' AND NEW.section_loc = 'DISTRIBUTION'
AND NEW.capa_loc = '12' AND NEW.modulo_loc = '6'
THEN
NEW.diametre := '12.2';
END IF;
答案 1 :(得分:1)
如果要更改已更新(或插入)的行中的列,请不要在触发函数中使用UPDATE
。将触发器声明为BEFORE UPDATE
,然后简单地分配新值。
您也不需要四个select语句从同一张表中读取四列。
但是,由于您只访问更新过的同一行中的列,因此甚至根本不需要SELECT。
因此您的触发功能可以简化为:
create or replace function maj_diam() returns trigger
as
$$
BEGIN
if new.fabricant = 'NEXANS'
and new.section = 'DISTRIBUTION'
and new.capcite = '12'
and new.modulo = '6'
then
new.diametre := '12.2';
end if;
return new;
end;
$$;
假设capcite,modulo和diametre实际上是数字,则不应将它们与varchar值进行比较。因此,上面的代码可能应该是:new.diametre := 12.2;
或new.capcite = 12
。
并且触发器定义需要更改为:
create trigger maj_diam
BEFORE update on support_fh
for each row
execute procedure maj_diam();