CREATE OR REPLACE FUNCTION verificar_pagina_inicial_final()
RETURNS trigger AS
$BODY$
BEGIN
IF NEW.pg_inicial < NEW.pg_final THEN
INSERT INTO artigos(id_artigo,id_editora,tipo_artigo,pg_inicial,pg_final)
VALUES(NEW.id_artigo,NEW.id_editora,NEW.tipo_artigo,NEW.pg_inicial,NEW.pg_final);
END IF;
END;
$BODY$
LANGUAGE plpgsql;
CREATE TRIGGER verifiar_paginas_novo_artigo
BEFORE INSERT OR UPDATE
ON artigos
FOR EACH ROW
EXECUTE PROCEDURE verificar_pagina_inicial_final();
当我尝试插入时,它会返回以下内容:
INSERT INTO public.artigos(id_artigo, id_editora, tipo_artigo, pg_inicial, pg_final)
VALUES (30, 3, 'teste', 1, 2);
退货:
ERROR: stack depth limit exceeded
HINT: Increase the configuration parameter "max_stack_depth" (currently 2048kB), after ensuring the platform's stack depth limit is adequate.
CONTEXT: SQL statement "INSERT INTO artigos(id_artigo,id_editora,tipo_artigo,pg_inicial,pg_final)
VALUES(NEW.id_artigo,NEW.id_editora,NEW.tipo_artigo,NEW.pg_inicial,NEW.pg_final)"
PL/pgSQL function verificar_pagina_inicial_final() line 4 at SQL statement
3条答案
按热度按时间2ul0zpep1#
触发器反复插入同一行。有多种方法可以防止这种情况。比如:
请参见:
如何防止postgresql触发器被另一个触发器触发?
EXECUTE FUNCTION
需要11个博士后。请参见:触发器函数不存在,但我很肯定它存在
但你似乎只是不同意
pg_inicial >= pg_final
. 你可以用一个CHECK
约束条件:一
CHECK
约束更简单、更快、更可靠。请参见:触发器与检查约束
Postgres9.x中有多少成本检查限制?
当然,当违反时会引发异常,这通常是一种解决方法。
安静地做,你回到触发器。更简单:
正常进行
INSERT
/UPDATE
,一个BEFORE
触发器必须RETURN NEW;
.RETURN NULL
取消该行。pexxcrt22#
因为您只“插入”新的列,所以在trigger函数中插入是完全不必要的——这就是将要插入的内容。如果new.pgèinical<new.pgèfinal“返回false,那么问题就变成了您想要什么。基本上有3种选择:
什么都不做,在这种情况下根本就没有触发器。
中止完整的insert语句。在这种情况下,创建一个check约束,并且根本没有触发器。或者在触发器中“引发异常”,但这不是一个好的计划。
静默忽略(跳过)这一行,否则继续查看文档
之前激发的行级触发器可以返回null,以指示触发器管理器跳过此行的其余操作(即,不会激发后续触发器,并且不会对此行执行插入/更新/删除操作)。
其中触发器功能实现如下:
4nkexdtk3#
假设这只是插入之前的测试,因为您不修改数据,也许
p、 s:我会做一个db小提琴来检查这个语法是否正确。这是小提琴,https://www.db-fiddle.com/f/9idx4bmjdk5ruzprfdevat/2 .
edit2:erwin brandstetter的答案是完整的,你应该添加一个约束而不是这个触发器。