2017-09-03 134 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