PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 19/08/2009 10:32:41

GoLDoRaK
Membre

[PROBLEME] Trigger sur PostgreSQL 8.3

Bonjour à tous,

Je recontre un problème avec les triggers de PostgreSQL. En effet, il m'est impossible de modifier une colonne de type boolean par l'intermédiaire d'un trigger.

Voici mon code procédural PL/pgSQL

1. DECLARE
2. cur    INTEGER;
3. im    INTEGER;
4. pfID   INTEGER;
5. dis    BOOLEAN;
6. BEGIN
7.
8. IF (TG_OP = 'UPDATE') THEN
9.          cur  = NEW.current_size;
10.         lim  = OLD.files_limit;
11.         pfID = NEW.photo_folder_id;
12. END IF;
13. 
14. IF (cur >= lim) THEN
15.         UPDATE t_photo_folder
16.         SET disabled = TRUE
17.         WHERE photo_folder_id = pfID;
18.         RETURN NULL;
18. END IF;
19.
20. RETURN NULL;
21. END;

J'obtient l'erreur suivante :

2009-08-18 10:22:49 ERROR  : ERREUR:  dépassement de limite (en profondeur) de la pile
HINT:  Augmenter le paramètre « max_stack_depth » après vous être assuré que la
limite de profondeur de la pile de la plateforme est adéquate.
CONTEXT:  instruction SQL « UPDATE t_photo_folder SET disabled = TRUE WHERE photo_folder_id =  $1  »
PL/pgSQL function "change_folder_status" line 15 at SQL statement
instruction SQL « UPDATE t_photo_folder SET disabled = TRUE WHERE photo_folder_id =  $1  »
PL/pgSQL function "change_folder_status" line 15 at SQL statement
instruction SQL « UPDATE t_photo_folder SET disabled = TRUE WHERE photo_folder_id =  $1  »
PL/pgSQL function "change_folder_status" line 15 at SQL statement
instruction SQL « UPDATE t_photo_folder SET disabled = TRUE WHERE photo_folder_id =  $1  »
PL/pgSQL function "change_folder_status" line 15 at SQL statement
instruction SQL « UPDATE t_photo_folder SET disabled = TRUE WHERE photo_folder_id =  $1  »

La table t_photo_folder
{
photo_folder_id INTEGER
name VARCHAR2
current_size INTEGER
files_limit INTEGER
disabled BOOLEAN
}

J'ai essayé de modifier la colonne files_limit avec mon UPDATE et de la changer par une autre valeur et cela fonctionne sans problème. J'ai pas de soucis aussi avec les intructions INSERT et DELETE.

Donc je ne comprends pas du tout d'où vient le problème. Merci d'avance de votre aide.

Dernière modification par GoLDoRaK (19/08/2009 10:34:05)

Hors ligne

#2 19/08/2009 10:53:30

gleu
Administrateur

Re : [PROBLEME] Trigger sur PostgreSQL 8.3

Hé bien, c'est assez simple une fois qu'on a pigé smile

Vous faites un UPDATE de t_photo_folder qui déclenche le trigger, qui exécute une fonction qui fait un UPDATE sur t_photo_folder  qui déclenche le trigger qui exécute une fonction qui fait un UPDATE sur t_photo_folder  qui déclenche le trigger qui... vous comprenez je pense smile

Bref, il ne faut pas faire un UPDATE sur la table qui est celle du trigger. Il vous faut modifier la fonction trigger par :

1. DECLARE
2. cur    INTEGER;
3. im    INTEGER;
4. pfID   INTEGER;
5. dis    BOOLEAN;
6. BEGIN
7.
8. IF (TG_OP = 'UPDATE') THEN
9.          cur  = NEW.current_size;
10.         lim  = OLD.files_limit;
11.         pfID = NEW.photo_folder_id;
12. END IF;
13. 
14. IF (cur >= lim) THEN
15.         disabled = TRUE;
18. END IF;
19.
20. RETURN NULL;
21. END;

Par contre, je ne suis pas sûr pour le RETURN NULL, tout dépend s'il s'agit d'un trigger BEFORE ou AFTER.


Guillaume.

Hors ligne

#3 19/08/2009 10:54:40

gleu
Administrateur

Re : [PROBLEME] Trigger sur PostgreSQL 8.3

Par contre, je trouve bizarre de comparer une limite de fichiers avec une taille... mais bon, rien à voir avec le soucis de récursion.


Guillaume.

Hors ligne

#4 19/08/2009 11:15:01

GoLDoRaK
Membre

Re : [PROBLEME] Trigger sur PostgreSQL 8.3

Merci pour votre réponse guillaume,

En effet, ca tombe dans une boucle infinie, je comprends mieux mon erreur.

Par contre, je ne peux pas mettre directement la colone disabled = true. Il m'envoie l'erreur suivante :

CONTEXT:  SQL statement in PL/PgSQL function "change_folder_status" near line 14
2009-08-18 11:12:16 ERROR  : ERREUR:  erreur de syntaxe sur ou près de « disabled »
LINE 1: disabled = TRUE
        ^

C'est un trigger after, donc il est appellé après un update sur la table t_photo_folder.

Pour répondre à votre curiosité, je compare le nombre total de fichiers dans un dossier à le nombre courant de fichier dans le dossier : en effet, il faut que je renomme ma colonne en current_files_number.

Hors ligne

#5 19/08/2009 11:20:16

gleu
Administrateur

Re : [PROBLEME] Trigger sur PostgreSQL 8.3

Oups, boulette de ma part. Il faut utiliser := et on doit utiliser la table NEW:

1. DECLARE
2. cur    INTEGER;
3. im    INTEGER;
4. pfID   INTEGER;
5. dis    BOOLEAN;
6. BEGIN
7.
8. IF (TG_OP = 'UPDATE') THEN
9.          cur  = NEW.current_size;
10.         lim  = OLD.files_limit;
11.         pfID = NEW.photo_folder_id;
12. END IF;
13. 
14. IF (cur >= lim) THEN
15.         NEW.disabled := TRUE;
18. END IF;
19.
20. RETURN NULL;
21. END;

De plus, à mon souvenir, si vous devez modifier un élément de la table, il faut que ce soit un trigger before. Et la valeur du RETURN doit être NEW.


Guillaume.

Hors ligne

#6 19/08/2009 11:28:08

GoLDoRaK
Membre

Re : [PROBLEME] Trigger sur PostgreSQL 8.3

En effet, je viens de changer mon trigger en BEFORE avec le code procédural suivante :

DECLARE
cur    INTEGER;
lim    INTEGER;
BEGIN

IF (TG_OP = 'UPDATE') THEN
        cur  = NEW.current_files_number;
        lim  = OLD.files_limit;
END IF;

IF (cur >= lim) THEN
        NEW.disabled := TRUE;
        RETURN NEW;
END IF;

RETURN NEW;
END;

cela marche parfaitement.

Merci beaucoup de votre aide.

Dernière modification par GoLDoRaK (19/08/2009 11:39:30)

Hors ligne

#7 19/08/2009 12:16:04

gleu
Administrateur

Re : [PROBLEME] Trigger sur PostgreSQL 8.3

Si votre trigger ne se déclenche que pour un UPDATE, vous pouvez encore simplifier le code:

BEGIN
IF NEW.current_files_number >= OLD.files_limit THEN
        NEW.disabled := TRUE;
END IF;
RETURN NEW;
END;

Guillaume.

Hors ligne

#8 19/08/2009 12:18:11

GoLDoRaK
Membre

Re : [PROBLEME] Trigger sur PostgreSQL 8.3

Je viens d'appliquer votre conseil, merci encore pour votre aide précieuse.

Hors ligne

Pied de page des forums