Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Postgres中超出堆栈深度限制_Sql_Database_Postgresql_Triggers_Plpgsql - Fatal编程技术网

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 什么都不做,在这种情况下根本就没有触发器。 中止完整的insert语句。在这种情况下,创建一个检查 约束,并且根本没有触发器。交替升起 触发器中出现异常,但这不是一个好计划。 静默忽略跳过此特定行,否则继续 看见 在can之前触发行级触发器 返回null,以指示触发器管理器跳过其余的 此行的操作,即不触发后续触发器,以及 此行未执行插入/更新/删除操作

其中触发功能的实现如下:

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;
$$ ;