sql - Postgres 中超出堆栈深度限制

标签 sql database postgresql triggers plpgsql

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

最佳答案

您的触发器一遍又一遍地插入同一行。有多种方法可以防止这种情况发生。喜欢:

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();

参见:

EXECUTE FUNCTION 需要 Postgres 11。参见:

但是您似乎只想禁止pg_inicial >= pg_final。您可以使用 CHECK 约束来做到这一点:

ALTER TABLE artigos ADD CONSTRAINT pg_final_must_be_greater_than_pg_inicial
CHECK (pg_inicial < pg_final);

CHECK 约束更简单、更快且更可靠。见:

当然,在违反时引发异常,这通常是要走的路。
默默地做,你又回到了触发器。更简单:

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

要正常进行 INSERT/UPDATEBEFORE 触发器必须 RETURN NEW;RETURN NULL 取消该行。

关于sql - Postgres 中超出堆栈深度限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62335546/

相关文章:

php - 迁移后测试数据(HTML -> PHP -> SQL)

MySQL 错误 "There can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT clause"即使我没有做错

android - 如何使用来自不同 DAO 的函数并使用协程与 Room 进行数据库事务?

mysql - 将两列相乘并显示在新的一列中

java - Docker-compose up springboot + postgres 连接被拒绝

sql - postgresql 从选择中插入

java - 在单个语句中在 java 中执行的多个查询

mysql - 查询获取一列的最高 ROW_NUM() 值 AS 仅 RANK() 另一列的值

database - Oracle DBCA 从何而来?

java - 使用 play framework v1.5 连接 db postgresql 时出错