Précédent   Forum des professionnels en informatique > Bases de données > PostgreSQL > Requêtes
Requêtes Forum d'entraide sur les requêtes SQL spécifiques à PostgreSQL, les triggers, les vues, etc.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 01/12/2011, 19h54   #1
Invité régulier
 
Inscription : décembre 2004
Messages : 67
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 67
Points : 6
Points : 6
Par défaut Réception requête dans fonction trigger

Bonjour,

Je suis entrain de réaliser une fonction pour un trigger et lorsque j'essaye de l'enregistrer je reçois une erreur dans l'assignation de la variable dernier_toquage. L'erreur est la suivante :

Citation:
ERREUR: erreur de syntaxe sur ou près de « SELECT »
LINE 1: SELECT SELECT date_toquage FROM projet.toquages WHERE avent...
^
QUERY: SELECT SELECT date_toquage FROM projet.toquages WHERE aventurier_id = $1 AND toquemon_id = $2
CONTEXT: SQL statement in PL/PgSQL function "est_toquable" near line 7

********** Erreur **********

ERREUR: erreur de syntaxe sur ou près de « SELECT »
État SQL :42601
Contexte : SQL statement in PL/PgSQL function "est_toquable" near line 7

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
CREATE FUNCTION projet.est_toquable() RETURNS TRIGGER AS $$
	-- Existe une variable NEW qui est un tuple (RECORD)
	dernier_toquage timestamp;
BEGIN
	IF (TG_OP = 'INSERT') THEN
		-- recupere la date du dernier toquage
		dernier_toquage := SELECT date_toquage FROM projet.toquages WHERE aventurier_id = NEW.aventurier_id AND toquemon_id = NEW.toquemon_id;
 
		-- si le tokemon n'a jamais été toqué ou si cela remonte à plus d'une semaine
		IF (dernier_toquage IS NULL) OR (dernier_toquage < NOW() - INTERVAL '7 days') THEN
			-- Incrementer la table aventurier (nombre_toquage)
			UPDATE projet.aventuriers SET nombre_toquage = nombre_toquage++ WHERE aventurier_id = NEW.aventurier_id;
			-- Incrementer la table toquemon (nombre_total_toquage)
			UPDATE projet.toquemon SET nombre_toquage = nombre_toquage++ WHERE toquemon_id = NEW.toquemon_id;
		-- sinon
		ELSE
			-- on leve une exception (j'ai mit une exception au hazard, faudra vérifier comment les récups en java)
			RAISE EXCEPTION invalid_transaction_terminaison;
		END IF;
	END IF;
END;
 
$$ LANGUAGE plpgsql;
Je ne comprend pas tellement d'où provient l'erreur.

Merci d'avance.
dib258 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/12/2011, 23h58   #2
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 647
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 647
Points : 2 644
Points : 2 644
bonjour,

et avec ceci est-ce que cela marche mieux ?

Code :
1
2
 
SELECT date_toquage INTO dernier_toquage FROM projet.toquages WHERE aventurier_id = NEW.aventurier_id AND toquemon_id = NEW.toquemon_id;
punkoff est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/12/2011, 15h46   #3
Invité régulier
 
Inscription : décembre 2004
Messages : 67
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 67
Points : 6
Points : 6
Je viens de tester et cela ne fonctionne pas non plus.

Je suis novice dans ce language et j'ai donc une question.

Dans ma fonction qui sera appelé par le trigger, j'aimerai récupéré une valeur dans la table ou l'insertion va être effectuée pour vérifier s'il n'y pas déjà une entrée qui est dedans depuis moins d'une semaine.

Je me demande si pour initialisé une variable je dois d'office la déclarer dans DECLARE (et qu'elle ne m'est pas passé par paramètre).

Ensuite comment faire pour assigner une valeur (qui provient d'une requete, ici le select) et qu'elle soit en integer (ou timestamp) mais je dois pouvoir manipuler dans une condition (juste en dessous dans le code) pour pouvoir vérifier si la date n'est pas inférieure à une semaine.

J'espère avoir mieux expliqué le problème.

@Punkoff : je ne comprend pas le INTO dernier_toquage dans la requette ? C'est pour assigner dans la variable dernier_toquage ? ou pour faire référence à une autre entrée ??

Merci d'avance !
dib258 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/12/2011, 17h30   #4
Modérateur
 
Inscription : octobre 2008
Messages : 1 508
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 508
Points : 2 040
Points : 2 040
A vue d'oeil voici les problèmes que tu dois corriger

1- dernier_toquage := SELECT date_toquage n'est pas possible , il faut faire le select INTO omme indiqué par punkoff pour assigner la variable

2- il manque un DECLARE au tout début pour déclarer la variable locale

3- nombre_toquage++ ne marchera pas en SQL, c'est nombre_toquage+1

4- ajouter RETURN NEW à la fin de la fonction.

5- en argument de RAISE EXCEPTION mettre une chaine de caractères au lieu d'un identifiant qui ne va pas exister.
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/12/2011, 19h05   #5
Invité régulier
 
Inscription : décembre 2004
Messages : 67
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 67
Points : 6
Points : 6
Je viens de retenter en prenant en compte toutes les choses que tu m'as dites et pourtant je reçois toujours une erreur.

J'ai declarer la variable dans DECLARE et j'ai rajouter le INTO dernier_toquage comme dit plus haut (ainsi que les +1 au lieu de ++).

Je reçois toujours la même erreur qui me cible le SELECT ou au alentour de ce SELECT.

Voici le code d'erreur ainsi que le code :

Citation:
ERREUR: erreur de syntaxe sur ou près de « SELECT »
LINE 1: SELECT SELECT date_toquage INTO $1 FROM projet.toquages W...
^
QUERY: SELECT SELECT date_toquage INTO $1 FROM projet.toquages WHERE aventurier_id = $2 AND toquemon_id = $3
CONTEXT: SQL statement in PL/PgSQL function "est_toquable" near line 7

********** Erreur **********

ERREUR: erreur de syntaxe sur ou près de « SELECT »
État SQL :42601
Contexte : SQL statement in PL/PgSQL function "est_toquable" near line 7
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
CREATE FUNCTION projet.est_toquable() RETURNS TRIGGER AS $$
	-- Existe une variable NEW qui est un tuple (RECORD)
DECLARE
	dernier_toquage integer;
BEGIN
	IF (TG_OP = 'INSERT') THEN
		-- recupere la date du dernier toquage
		dernier_toquage := SELECT date_toquage INTO dernier_toquage FROM projet.toquages WHERE aventurier_id = NEW.aventurier_id AND toquemon_id = NEW.toquemon_id;
		-- SELECT date_toquage FROM projet.toquages WHERE aventurier_id = NEW.aventurier_id AND toquemon_id = NEW.toquemon_id;
 
		-- si le tokemon n'a jamais été toqué ou si cela remonte à plus d'une semaine
		IF (dernier_toquage IS NULL) OR (dernier_toquage < NOW() - INTERVAL '7 days') THEN
			-- Incrementer la table aventurier (nombre_toquage)
			UPDATE projet.aventuriers SET nombre_toquage = nombre_toquage+1 WHERE aventurier_id = NEW.aventurier_id;
			-- Incrementer la table toquemon (nombre_total_toquage)
			UPDATE projet.toquemon SET nombre_toquage = nombre_toquage+1 WHERE toquemon_id = NEW.toquemon_id;
		-- sinon
		ELSE
			-- on leve une exception (j'ai mit une exception au hazard, faudra vérifier comment les récups en java)
			RAISE EXCEPTION "Deja toque cette semaine";
		END IF;
	END IF;
 
	RETURN NEW;
END;
 
$$ LANGUAGE plpgsql;
dib258 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/12/2011, 19h28   #6
Modérateur
 
Inscription : octobre 2008
Messages : 1 508
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 508
Points : 2 040
Points : 2 040
Au lieu de:
Code :
		dernier_toquage := SELECT date_toquage INTO dernier_toquage FROM projet.toquages WHERE aventurier_id = NEW.aventurier_id AND toquemon_id = NEW.toquemon_id;
Il faut:
Code :
		SELECT date_toquage INTO dernier_toquage FROM projet.toquages WHERE aventurier_id = NEW.aventurier_id AND toquemon_id = NEW.toquemon_id;
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/12/2011, 22h39   #7
Invité régulier
 
Inscription : décembre 2004
Messages : 67
Détails du profil
Informations forums :
Inscription : décembre 2004
Messages : 67
Points : 6
Points : 6
Merci beaucoup !

Cela marche au poil maintenant !!!

Une autre question, est ce que l'on peut changer les données dans la variables NEW ? parce qu'a la fin on RETURN l'entrée new. Donc logiquement si on modifie les valeurs de la variables NEW on pourrait changer avant l'insertion dans la BDD.
dib258 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/12/2011, 16h57   #8
Modérateur
 
Inscription : octobre 2008
Messages : 1 508
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 508
Points : 2 040
Points : 2 040
Citation:
Envoyé par dib258 Voir le message
Une autre question, est ce que l'on peut changer les données dans la variables NEW ? parce qu'a la fin on RETURN l'entrée new. Donc logiquement si on modifie les valeurs de la variables NEW on pourrait changer avant l'insertion dans la BDD.
Oui on peut dans le cas d'un trigger déclenché avant l'update ou l'insert (CREATE TRIGGER BEFORE...)
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 15h00.


 
 
 
 
Partenaires

Hébergement Web