Postgresql,检查插入时触发错误

时间:2017-09-03 16:31:45

标签: postgresql triggers

我试图使用触发器检查我何时在我的桌子上插入数据"历史记录",我需要在插入之前检查,如果表格的某一行"历史记录"与我插入的数据具有相同的IDU。我已经使用了这个触发器和这个功能,但是我无法使它工作..

My table "Historial"

这是我的触发器:

CREATE TRIGGER VerificarInsercion
BEFORE INSERT ON public."Historial"
FOR EACH ROW 
EXECUTE PROCEDURE VerificarHistorial();

(我已尝试删除" FOR EACH ROW",因为我想要的只运行一次而不是每一行)

最后,我的函数verificarhistorial():

BEGIN
  IF (SELECT Count (*) FROM public."Historial" WHERE estado = 1 AND "IDU" = NEW."IDU") < 1 THEN 
      INSERT INTO public."Historial" (usuario, vehiculo, mercancia, "combustibleInicial", ruta, "horaSalida", estado, "IDU", fecha)
      VALUES (NEW.usuario, NEW.vehiculo, NEW.mercancia, NEW."combustibleInicial", NEW.ruta, NEW."horaSalida", NEW.estado, NEW."IDU", NEW.fecha);
  END IF;
  RETURN null;
END;

当我在&#34; Historial&#34;:

中插入一些数据时
INSERT INTO public."Historial" (usuario, vehiculo, mercancia, "combustibleInicial", ruta, "horaSalida", estado, "IDU", fecha) VALUES ('David', '3424SDA', 200, 50, 'Cáceres-Sevilla', 'dom, 3 sep, 05:20 PM', 1, 50, '2017-09-03T15:21:07.442Z')

我收到此错误:

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 "SELECT (SELECT Count (*) FROM public."Historial" WHERE estado = 1 AND "IDU" = NEW."IDU") < 1"
PL/pgSQL function verificarhistorial() line 2 at IF
SQL statement "INSERT INTO public."Historial" (usuario, vehiculo, mercancia, "combustibleInicial", ruta, "horaSalida", estado, "IDU", fecha)
      VALUES (NEW.usuario, NEW.vehiculo, NEW.mercancia, NEW."combustibleInicial", NEW.ruta, NEW."horaSalida", NEW.estado, NEW."IDU", NEW.fecha)"
PL/pgSQL function verificarhistorial() line 3 at SQL statement

我检查了其他类似的回答,没有结果。

有些想法要创建一个函数来检查是否有任何行与插入数据具有相同的IDU?

2 个答案:

答案 0 :(得分:2)

每次向表中插入新行时都会调用触发器函数。如果您尝试在函数内插入一行,则再次调用该函数,然后再次调用,依此类推。这样就可以实现堆栈溢出

不要尝试在插入...

上调用的触发器函数中插入行
BEGIN
    IF EXISTS (SELECT 1 FROM "Historial" WHERE estado = 1 AND "IDU" = NEW."IDU") THEN 
        RETURN null;
    END IF;
    RETURN new;
END; $$;

实际上,如果您创建部分唯一索引,则不需要触发器:

create unique index on "Historial" ("IDU") where estado = 1

答案 1 :(得分:1)

您不应该在触发器中插入新行,这会导致无限递归。我认为可以通过创建像这样的Unique Index来完成:

set search_path = public;
create unique index on "Historial" ("IDU") where estado = 1;

同样的问题,但对于Stackoverflow中已经回答的Update Command,请参阅以下链接:

Update a table with a trigger after update