Sql Postgres中超出堆栈深度限制
当我尝试插入时,它会返回以下内容:Sql Postgres中超出堆栈深度限制,sql,database,postgresql,triggers,plpgsql,Sql,Database,Postgresql,Triggers,Plpgsql,当我尝试插入时,它会返回以下内容: CREATE TRIGGER verifiar_paginas_novo_artigo BEFORE INSERT OR UPDATE ON artigos FOR EACH ROW EXECUTE PROCEDURE verificar_pagina_inicial_final(); 返回: 假设这只是插入之前的测试,因为您不修改数据,可能 ERROR: stack depth limit exceeded HINT: Increas
CREATE TRIGGER verifiar_paginas_novo_artigo
BEFORE INSERT OR UPDATE
ON artigos
FOR EACH ROW
EXECUTE PROCEDURE verificar_pagina_inicial_final();
返回:
假设这只是插入之前的测试,因为您不修改数据,可能
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
p、 我会做一个DB小提琴来检查这个语法是否正确。
这是小提琴
Edit2:Erwin Brandstetter的答案已经完成,您应该添加一个约束而不是此触发器。您的触发器反复插入同一行。有多种方法可以防止这种情况。比如:
IF (NEW.pg_inicial < NEW.pg_final) THEN
RETURN NEW;
ELSE
RETURN NULL;
END IF;
检查约束更简单、更快、更可靠。见:
当然,违反时会引发异常,这通常是一种解决方法。
若要安静地执行,则返回触发器。简单一点:
ALTER TABLE artigos ADD CONSTRAINT pg_final_must_be_greater_than_pg_inicial
CHECK (pg_inicial < pg_final);
要正常进行插入/更新,BEFORE触发器必须返回NEW;。RETURN NULL取消该行。因为您只插入新列,所以触发器函数中的insert是完全不必要的-这就是要插入的内容。如果NEW.pg_inical
CREATE OR REPLACE FUNCTION verificar_pagina_inicial_final()
RETURNS trigger LANGUAGE plpgsql AS
$func$
BEGIN
IF NEW.pg_inicial < NEW.pg_final THEN
RETURN NEW; -- proceed
ELSE
RETURN NULL; -- skip insert / update
END IF;
END
$func$;
您的触发器和过程似乎形成了一个无限递归。ON INSERT触发器调用本身在同一个表上执行INSERT的SP。感谢您的回答。。。那么,当他插入函数时,他会再次调用触发器吗?有没有办法让我只做一次?这个问题有答案吗?
CREATE TRIGGER verifiar_paginas_novo_artigo
BEFORE INSERT OR UPDATE ON artigos
FOR EACH ROW
WHEN (pg_trigger_depth() < 1) -- !
EXECUTE FUNCTION verificar_pagina_inicial_final();
ALTER TABLE artigos ADD CONSTRAINT pg_final_must_be_greater_than_pg_inicial
CHECK (pg_inicial < pg_final);
CREATE OR REPLACE FUNCTION verificar_pagina_inicial_final()
RETURNS trigger LANGUAGE plpgsql AS
$func$
BEGIN
IF NEW.pg_inicial < NEW.pg_final THEN
RETURN NEW; -- proceed
ELSE
RETURN NULL; -- skip insert / update
END IF;
END
$func$;
create or replace
function verificar_pagina_inicial_final()
returns trigger
language plpgsql
as $$
begin
if new.pg_inicial < new.pg_final
then
return new;
else
return null;
end if;
end;
$$ ;