Précédent   Forum des professionnels en informatique > Bases de données > PostgreSQL
PostgreSQL Forum PostgreSQL. Avant de poster -> F.A.Q PostGreSQL Tutoriels PostGreSQL
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 29/06/2006, 11h09   #1
Nouveau Membre du Club
 
Inscription : mai 2002
Messages : 75
Détails du profil
Informations forums :
Inscription : mai 2002
Messages : 75
Points : 32
Points : 32
Par défaut Création de Table de taille fixe

Salut tous!
Je cherche à créer une table qui contiendrait un nombre maximal d'enregistrements. Lorsque ce nombre est atteint, à l'insertion suivante, il faudrait supprimer l'enregistrement le plus vieux et insérer le nouveau.

Je vais essayer de faire ça avec des trigger (ou autre suivant ce que je trouverai), mais je voudrais savoir si il existe une méthode/fonction/commande déjà prévue pour ce fonctionnement en SQL/PostgreSQL.

Merci pour vos suggestions.

PierrotY est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/06/2006, 11h36   #2
Membre chevronné
 
Avatar de gerald2545
 
Inscription : février 2003
Messages : 643
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 643
Points : 660
Points : 660
je pense que la solution du trigger est inévitable.....
gerald2545 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/06/2006, 16h12   #3
Nouveau Membre du Club
 
Inscription : mai 2002
Messages : 75
Détails du profil
Informations forums :
Inscription : mai 2002
Messages : 75
Points : 32
Points : 32
Je me suis lancé dans les triggers, et la création de fonctions. Mais j'ai un soucis... comment passer un nom de table en argument de fonction? J'ai essayé le type name, le type text, mais ça n'est pas accepté!

Quelqu'un sait-il comment passer un nom de table en argument d'une fonction?
PierrotY est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/06/2006, 18h05   #4
Membre chevronné
 
Avatar de gerald2545
 
Inscription : février 2003
Messages : 643
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 643
Points : 660
Points : 660
tu peux donner ton code STP et dire exactement ce que tu veux faire, ainsi que les messages d'erreur éventuels?
si je comprends bien tu veux créer une seule fonction qui est appelée par des triggers posés sur différentes tables?
gerald2545 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/07/2006, 10h51   #5
Nouveau Membre du Club
 
Inscription : mai 2002
Messages : 75
Détails du profil
Informations forums :
Inscription : mai 2002
Messages : 75
Points : 32
Points : 32

J'ai fini ma fonction, ... je vais voir comment l'utiliser dans un(e) trigger. Si d'ailleurs vous avez quelques lignes à me suggérer pour accélérer mes recherches, tout est le bien venu.

En attendant, voilà la fonction:

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
29
30
 
CREATE OR REPLACE FUNCTION fc_init_table(varchar) RETURNS INTEGER AS '
DECLARE
	query TEXT;
	strTypOp TEXT;
	valdate TIMESTAMP;
	curseur REFCURSOR;
 
BEGIN
 
	query := ''SELECT date FROM '' || $1 || '' ORDER BY date LIMIT 1'';
	OPEN curseur FOR EXECUTE query;
	FETCH curseur INTO valdate;
 
	IF EXTRACT(WEEK FROM valdate) != EXTRACT(WEEK FROM now()) THEN
		-- On vide la table histo chaque semaine
		query := ''DELETE FROM '' || $1;
		EXECUTE query;
		-- On insert le premier enregistrement
		strTypOp := ''''''I'''''';
		query := ''INSERT INTO '' || $1 || '' VALUES(DEFAULT, CURRENT_DATE+CURRENT_TIME(0), 1, ''
|| strTypOp || '', 0, 0, 0, 0)'';
		EXECUTE query;
	END IF;
 
	RETURN 0;
 
END;
'
LANGUAGE plpgsql;
PierrotY est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/07/2006, 13h36   #6
Membre chevronné
 
Avatar de gerald2545
 
Inscription : février 2003
Messages : 643
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 643
Points : 660
Points : 660
si je ne m'abuse, ta fonction ne correspond pas à la description de ce que tu désirais faire en première intention?
Cette fonction va être appelée à chaque insertion dans ta base de données (tu as beaucoup d'insertions à faire chaque semaine?)
Sinon, ce que tu peux faire c'est d'exécuter un script 1 fois en fin de semaine qui va effacer le contenu de ta table pour les données de la semaine écoulée.
J'ai vu dans un post récent que c'était possible d'automatiser ce genre de tâche.....
A+
gerald2545 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/07/2006, 15h03   #7
Nouveau Membre du Club
 
Inscription : mai 2002
Messages : 75
Détails du profil
Informations forums :
Inscription : mai 2002
Messages : 75
Points : 32
Points : 32


HHmmm, ... oui en effet! Après réflexion, c'était plus simple (voire, c'était ce qui était demandé) de vider la table toutes les semaines. Bref, changement de fonction, mais mon soucis persistait pour le nom de la table (ce qui est règlé maintenant).

Mais [Résolu] attendra un peu...

Tu disais qu'on pouvais automatisé des tâches... comme une crontab interne à la table?
PierrotY est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/07/2006, 16h32   #8
Membre chevronné
 
Avatar de gerald2545
 
Inscription : février 2003
Messages : 643
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 643
Points : 660
Points : 660
Citation:
Envoyé par PierrotY


HHmmm, ... oui en effet! Après réflexion, c'était plus simple (voire, c'était ce qui était demandé)


Citation:
Envoyé par PierrotY
Tu disais qu'on pouvais automatisé des tâches... comme une crontab interne à la table?
va voir ici : http://www.pgadmin.org/index.php, http://www.pgadmin.org/docs/1.4/pgagent.html
gerald2545 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/07/2006, 11h39   #9
Nouveau Membre du Club
 
Inscription : mai 2002
Messages : 75
Détails du profil
Informations forums :
Inscription : mai 2002
Messages : 75
Points : 32
Points : 32


... ce doit être la chaleur, ... la fatigue ou je ne sais pas quoi, mais, j'arrive pas à créer mon trigger!
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
29
30
31
32
33
34
35
36
 
DROP FUNCTION fc_init_table(varchar);
CREATE FUNCTION fc_init_table(varchar) RETURNS TRIGGER AS '
DECLARE
	query TEXT;
	strTypOp varchar(4);
	valdate TIMESTAMP;
	idvaleur INTEGER;
	curseur REFCURSOR;
	dpSemVal DOUBLE PRECISION;
 
BEGIN
 
	query := ''SELECT date, idval FROM '' || $1 || '' ORDER BY idVal LIMIT 1'';
	OPEN curseur FOR EXECUTE query;
	FETCH curseur INTO valdate, idvaleur;
 
	-- dpSemVal := EXTRACT(WEEK FROM valdate);
	IF EXTRACT(WEEK FROM valdate) != EXTRACT(WEEK FROM now()) THEN
		-- On vide la table histo
		query := ''DELETE FROM '' || $1;
		EXECUTE query;
		-- On insert le premier enregistrement
		strTypOp := ''''''I'''''';
		query := ''INSERT INTO '' || $1 || '' VALUES(DEFAULT,
CURRENT_DATE+CURRENT_TIME(0), 1, '' || strTypOp || '', 0, 0, 0, 0)'';
		EXECUTE query;
	END IF;
 
	RETURN 0;
 
END;
'
LANGUAGE plpgsql;
 
CREATE TRIGGER trig_init_histo00 BEFORE INSERT OR UPDATE ON histo00 EXECUTE PROCEDURE fc_init_table('histo00');
Quand j'exécute tout ça, j'ai le message d'erreur en retour
Code :
1
2
 
psql:./tst.sql:34: ERREUR:  La fonction fc_init_table() n'existe pas
...
PierrotY est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2006, 14h33   #10
Nouveau Membre du Club
 
Inscription : mai 2002
Messages : 75
Détails du profil
Informations forums :
Inscription : mai 2002
Messages : 75
Points : 32
Points : 32
Ben en fait, c'était simplement que la fonction utilisée pour un trigger ne doit pas prendre d'arguments! Tout simplement.
Pour ceux que ça intéresse, voilà le résultat au final:

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 
CREATE FUNCTION fc_init_table(TEXT) RETURNS INTEGER AS '
DECLARE
	query TEXT;
	strTypOp varchar(4);
	valdate TIMESTAMP;
	curseur REFCURSOR;
 
BEGIN
 
	query := ''SELECT date FROM histo'' || $1 || '' ORDER BY idVal LIMIT 1'';
	OPEN curseur FOR EXECUTE query;
	FETCH curseur INTO valdate;
 
	IF EXTRACT(WEEK FROM valdate) != EXTRACT(WEEK FROM now()) THEN
		-- On vide la table histo
		query := ''DELETE FROM histo'' || $1;
		EXECUTE query;
		-- On reset la séquence
		query := ''SELECT setval(''''idval'' || $1 || ''_seq'''', 1)'';
		EXECUTE query;
		-- On insert le premier enregistrement
		strTypOp := ''''''I'''''';
		query := ''INSERT INTO histo'' || $1 ||
				'' VALUES(1, CURRENT_DATE+CURRENT_TIME(0), 1, ''
				|| strTypOp || '', 0, 0, 0, 0)'';
		EXECUTE query;
	END IF;
 
	RETURN 0;
 
END;
'
LANGUAGE plpgsql;
 
CREATE FUNCTION fc_init_histo00() RETURNS TRIGGER AS '
DECLARE
	query TEXT;
BEGIN
	query := ''SELECT * FROM fc_init_table(''''00'''');'';
	EXECUTE query;
	RETURN NEW;
END;
'
LANGUAGE plpgsql;
 
CREATE TRIGGER trig_init_histo00 BEFORE INSERT OR UPDATE ON histo00
EXECUTE PROCEDURE fc_init_histo00();
Ca fait plus de fonctions que je ne le souhaitais, ... mais j'ai pas pu faire plus court. Un grand merci à gerald2545. J'ai jeté un oeil sur pgAdmin, ... mais ça semble trop lourd pour être utilisé là où la base sera installée.
Merci encore, ... et bon code!
PierrotY 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 00h07.


 
 
 
 
Partenaires

Hébergement Web