2017-09-03 1 views
0

En essayant d'utiliser un déclencheur pour vérifier quand j'insère une donnée sur ma table "historial", je dois vérifier avant d'insérer, si une ligne de la table "Historial" a le même IDU que les données que je suis en train d'insérer. J'utiliser ce déclencheur et cette fonction, mais je ne peux pas le faire fonctionner ..Postgresql, déclenche erreur lors de la vérification de l'insertion

My table "Historial"

Que son mon déclencheur:

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

(j'ai essayé d'enlever « POUR CHAQUE LIGNE », puisque ce que je veux est d'exécuter une seule fois et non pour chaque ligne)

et enfin, mon verificarhistorial() fonction:

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; 

Lorsque j'insère des données dans "Historial":

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') 

Je reçois cette erreur:

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 

J'ai vérifié d'autres réponses similaires, sans résultat.

Une idée pour faire une fonction qui vérifie si une ligne ont le même IDU que les données d'insertion?

+0

Vous n'avez pas besoin d'un déclencheur pour cela, il suffit de créer un INDEX UNIQUE sur ce champ. Vous ne pouvez pas sélectionner sur la table que vous créez le déclencheur. –

+0

oui mais, IDU peut être dupliqué sur la table, une seule ligne peut avoir "estado" == 1 et le même IDU, mais d'autres lignes peuvent avoir le même IDU mais "estado == 0" –

+0

Le vous devez créer un APRES INSÉRER le déclencheur. –

Répondre

2

La fonction de déclenchement est appelée chaque fois que vous insérez une nouvelle ligne dans la table. Si vous essayez d'insérer une ligne à l'intérieur de la fonction, la fonction est appelée à nouveau, et encore et encore. De cette façon, vous obtenez débordement de pile.

Ne pas essayer d'insérer une ligne dans une fonction de déclenchement appelé insert ...

BEGIN 
    IF EXISTS (SELECT 1 FROM "Historial" WHERE estado = 1 AND "IDU" = NEW."IDU") THEN 
     RETURN null; 
    END IF; 
    RETURN new; 
END; $$; 

En fait, vous n'avez pas besoin d'un déclencheur si vous créez un index unique partiel:

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

Vous ne devez pas insérer une nouvelle ligne dans votre déclencheur et cela a provoqué une récursion infinie. Je pense que cela peut être fait en créant un Unique Index comme celui-ci:

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

La même question, mais pour le Update Command déjà répondu dans le StackOverflow, Voir le lien ci-dessous:

Update a table with a trigger after update