2017-03-29 3 views
0

J'ai cette table sur PostgreSQL et je voudrais faire un déclencheur que chaque fois que je modifier une ligne de la table publications la last_edit_date est mis à jour now():profondeur Stack Limite INSERT déclencheur

CREATE FUNCTION trigger_update_question_timestamp() 
    RETURNS "trigger" AS $func$ 
BEGIN 
    UPDATE publications SET last_edit_date = now() WHERE publicationid = NEW.publicationid; 
    RETURN NULL; 
END; 
$func$ LANGUAGE plpgsql; 

CREATE TRIGGER answer_update_question_timestamp AFTER INSERT OR UPDATE ON publications 
    FOR EACH ROW EXECUTE PROCEDURE trigger_update_question_timestamp(); 

CREATE TABLE publications 
(
    publicationid SERIAL PRIMARY KEY, 
    body VARCHAR(1000) NOT NULL , 
    creation_date TIMESTAMP DEFAULT now() NOT NULL, 
    userid INTEGER NOT NULL, 
    last_edit_date TIMESTAMP, 
    CONSTRAINT body_length CHECK (CHAR_LENGTH(body) >= 10 AND CHAR_LENGTH(body) <= 1000), 
    CONSTRAINT "FK_publications_users" 
     FOREIGN KEY ("userid") REFERENCES users ("userid") ON DELETE SET NULL ON UPDATE CASCADE 
); 

Je m à l'aide PhpStorm et quand je modifier manuellement une ligne que je reçois l'erreur suivante:

[54001] 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. Where: SQL statement "SELECT 1 FROM ONLY "public"."users" x WHERE "userid" OPERATOR(pg_catalog.=) $1 FOR KEY SHARE OF x" SQL statement "UPDATE publications SET last_edit_date = now() WHERE publicationid = NEW.publicationid" PL/pgSQL function trigger_update_question_timestamp() 

Qu'est-ce que cela signifie exactement? Est-ce que cela a à voir avec mon déclencheur ou toute autre définition?

Répondre

2

Votre déclencheur est récursif, c'est-à-dire que la fonction de déclenchement exécute un UPDATE qui appelle à nouveau la fonction de déclenchement.

La solution est d'utiliser un déclencheur BEFORE INSERT OR UPDATE, qui modifie NEW comme suit:

BEGIN 
    NEW.last_edit_date := current_timestamp; 
    RETURN NEW; 
END; 
+0

Que voulez-vous dire? @Laurenz Albe Quelque chose comme 'BEGIN UPDATE publications SET NEW.last_edit_date = CURRENT_TIMESTAMP WHERE publicationid = NEW.publicationid; RETURN NULL; FIN; ' Il dit que le nouveau des publications n'existe pas –

+1

Non, c'est le corps complet (j'ai édité la réponse pour indiquer cela). Pas de "UPDATE", pas de rien. Tout ce que vous faites est de modifier la valeur * avant * que la ligne ne soit insérée. N'oubliez pas qu'il doit s'agir d'un déclencheur "AVANT". –