2017-09-03 132 views
0

我试图使用触发器来检查当我在我的表“历史”插入数据,我需要检查插入之前,如果表“行”的表的某一行有与我插入的数据相同的IDU。我已经使用这个触发这个功能,但我不能让它工作..Postgresql,检查插入时触发错误

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; 

当我在 “讲史” 插入一些数据:

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插入数据?

+0

你不需要一个触发器,只需在该字段上创建一个UNIQUE INDEX。您无法在创建触发器的表上进行选择。 –

+0

是的,但是,IDU可以在表上复制,只有一行可以具有“estado”== 1和相同的IDU,但其他行可以具有相同的IDU但“estado == 0” –

+0

您需要创建在INSERT触发器之后。 –

回答

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

你不应该在你的触发器中插入一个新行,这是造成无限递归。我认为它可以通过创建一个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