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 09/11/2010 23:56:30

LeHibou
Membre

Trigger anniversaire

Bonjour à tous,

Je souhaite mettre en place un trigger anniversaire, me permettant de n'oublier personne en route.
J'ai également créé une table "alarme" qui recoit ce genre d'infos.

Constat : les années  avancent : il faut donc une base fixe. C'est la raison pour laquelle j'ai pensé à ne retenir que le jour et le mois de l'anniversaire.

Voici ce que j'ai, et qui ne fonctionne pas :

CREATE OR REPLACE FUNCTION mf.verific() RETURNS trigger AS
$BODY$begin
perform client.anniv
from test.client;

if (date_part('month',timestamp 'client.anniv') = date_part('month',timestamp 'current_date) and (date_part('day',timestamp 'client.anniv') = date_part('day',timestamp 'current_date')  and (tg_op = 'INSERT' or tg_op = 'UPDATE')
then insert into test.alarme (alarm_anniv)
Values ('new.anniv');
end if;

return new;
end;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

Mes tables:

-- Table: test.client

-- DROP TABLE test.client;

CREATE TABLE test.client
(
  anniv date NOT NULL,
  CONSTRAINT client_pkey PRIMARY KEY (anniv)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE test.client OWNER TO "me";

-- Trigger: mp on test.client

-- DROP TRIGGER mp ON test.client;

CREATE TRIGGER mp
  BEFORE INSERT OR UPDATE
  ON test.client
  FOR EACH ROW
  EXECUTE PROCEDURE test.verific();
-- Table: test.alarme

-- DROP TABLE test.alarme;

CREATE TABLE test.alarme
(
  alarm_anniv date NOT NULL,
  CONSTRAINT verif_pkey PRIMARY KEY (alarm_anniv)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE test.alarme OWNER TO "me";

Attention, c'est pour le test car ici, il ne renvoit que la valeur de la date d'anniv (inutile si on ne sait pas à qui elle appartient...). Egalement, la clé primaire interdit deux personne d'avoir le même jour d'anniv (débile, mais c'est pour le test).

Si vous avez une idée sur la façon d'aborder le sujet, je suis preneur...

A bientôt,

Le Hibou

Hors ligne

#2 10/11/2010 01:33:02

gleu
Administrateur

Re : Trigger anniversaire

Quel est le but de "perform client.anniv from test.client;" ? parce que ça n'a aucun sens.


Guillaume.

Hors ligne

#3 10/11/2010 09:34:24

LeHibou
Membre

Re : Trigger anniversaire

Je pensais que cela sélectionnait la bonne colonne pour l'analyse globale.

Mais la nuit aidant, j'ai l'impression que je serai plus efficace pour gérer cela par une spreadsheat, pour 2 raisons :

- le trigger ne s'enclenche que si on ajoute ou modifie la table.
- si une période creuse s'annonce, le trigger va louper des anniversaires (cas des 367 clients ajoutés tous le premier jour).

Mais d'un autre côté, cela oblige à faire des copier coller quotidien de la table dans un tableur, ce qui n'est pas une solution en soi (limite numerique du tableur) et surtiout absence totale d'automatisation.

Si on n'opère pas par trigger (sauf si pour vous, c'est cohérent), comment aborder ce problème de rappel d'anniversaire ?


Je suis preneur de toute piste,

A bientôt !

Le Hibou

Hors ligne

#4 10/11/2010 09:47:36

Marc Cousin
Membre

Re : Trigger anniversaire

C'est exactement le problème qui gênait gleu je pense : un trigger n'est exécuté qu'en cas de modification de la table.

Il n'y a pas vraiment de solution à votre problème à l'heure actuelle dans PostgreSQL: il n'y a pas de planificateur d'événements interne. Il existe pgagent, qui fait partie de pgadmin, et qui permet de déclencher des événements suite à horodatage. Mais rien d'intégré à PostgreSQL. Ou sinon, une tâche planifiée du système d'exploitation, qui déclenche un script SQL.


Marc.

Hors ligne

#5 10/11/2010 10:18:22

LeHibou
Membre

Re : Trigger anniversaire

Ah..
Et comme je ne sais pas si c'est une fonctionnalité qui intéresse grand monde, je pense que je suis "condamné" à faire par spreadsheet (mon niveau pour programmer une telle chose étant bien insuffisant).

Mais au cas où, je peux lancer une demande aux dévelopeurs de Postgres ? Ou cela paraîtra complètement déplacé ?

Merci en tout cas,

A bientôt,

LeHibou

Hors ligne

#6 10/11/2010 10:30:20

Marc Cousin
Membre

Re : Trigger anniversaire

Complètement déplacé: ils sont déjà en train de discuter de la question. C'est une des choses qui reviennent régulièrement, le débat tournant autour de 'c'est pas le boulot de la base de données' et 'oui mais c'est bien pratique' smile

Mais il se pourrait que ça arrive quand même dans une version future, vu que l'infrastructure nécessaire commence à être mise en place (en raison de l'implémentation d'une autre fonctionnalité).


Marc.

Hors ligne

#7 10/11/2010 12:24:56

Re : Trigger anniversaire

Marc Cousin a écrit :

Complètement déplacé: ils sont déjà en train de discuter de la question. C'est une des choses qui reviennent régulièrement, le débat tournant autour de 'c'est pas le boulot de la base de données' et 'oui mais c'est bien pratique' smile

Mais il se pourrait que ça arrive quand même dans une version future, vu que l'infrastructure nécessaire commence à être mise en place (en raison de l'implémentation d'une autre fonctionnalité).

Oui c'est bien pratique de pouvoir intégrer dans la base de données du scheduling de tâches. Ça permet de tout récupérer/réinstaller avec de simples dump/restore.

Il y a ce genre de fonctionalités dans oracle maintenant.

Hors ligne

#8 10/11/2010 12:38:24

gleu
Administrateur

Re : Trigger anniversaire

Oui, ce serait pratique. Mais c'est clairement pas le boulot de la base de données. Ajouter un planificateur pour faire ce que fait cron, non. C'est du code à développer, à tester, à maintenir. Ça représente beaucoup de travail, donc de temps, et il est bien préférable que les développeurs de PostgreSQL travaillent sur des fonctionnalités réellement base de données et non pas sur des fonctionnalités déjà disponibles ailleurs (cron sous Unix, tâche planifiée sous Windows... voire pgagent). Et le fait que ce soit dans Oracle n'est pas un argument convaincant.

Par contre, si c'est ajouter cette fonctionnalité pour disposer d'une fonctionnalité autre qui elle est vraiment base de données, alors oui. D'une pierre, deux coups, je ne peux que être pour.


Guillaume.

Hors ligne

#9 10/11/2010 12:51:23

Marc Cousin
Membre

Re : Trigger anniversaire

Voila, on a l'argument d'un des deux clans. On peut aussi imaginer, pour l'autre point de vue, qu'avoir ça dans la base de données, ça fait encore ça de moins de spécifique à l'architecture sur laquelle on va le déployer. C'est ce qu'apprécient les DBA Oracle, pas besoin de paramétrer cron sous unix ou le planificateur sous windows, avec deux procédures différentes, et devoir aussi superviser la bonne exécution des cron, etc…


Marc.

Hors ligne

#10 10/11/2010 13:47:16

Re : Trigger anniversaire

Marc Cousin a écrit :

C'est ce qu'apprécient les DBA Oracle, pas besoin de paramétrer cron sous unix ou le planificateur sous windows, avec deux procédures différentes, et devoir aussi superviser la bonne exécution des cron, etc…

Ben oui.

J'ajoute que bien souvent (pour ne pas dire presque toujours), ce ne sont pas les mêmes personnes qui s'occupent des aspects systèmes du serveur, et ceux qui s'occupent des bases de données.

La crontab, c'est du système.

À chaque fois qu'il y a une migration de serveur, c'est toujours le même problème : Qui va sauvegarder / restaurer les crontabs :

L'admin : Ah non, moi je ne m'occupe que de la crontab système. Pas des crontabs utilisateur.
L'opérateur : Ah ben non, moi je n'ai les droits que pour effectuer les dump/restore.
Le DBA : Ah ben il est pas prévu que je travaille de nuit moi.

Enfin je carricature (un peu)  ; mais c'est toujours le genre de problèmes qu'il y a...

Hors ligne

#11 10/11/2010 15:18:54

LeHibou
Membre

Re : Trigger anniversaire

Ok, je comprends mieux les tenants et les aboutissants.

A moins qu'un script de ce genre fasse l'affaire (supposé "Trust", sinon pgpass)? :

#!bin/bash
psql -U lehibou -h monserveur -d mabase -c "perform client.anniv from test.client if (date_part('month',timestamp 'client.anniv') = date_part('month',timestamp 'current_date) and (date_part('day',timestamp 'client.anniv') = date_part('day',timestamp 'current_date')  and (tg_op = 'INSERT' or tg_op = 'UPDATE') then insert into test.alarme (alarm_anniv) Values ('new.anniv'); end if; return new; end;

exit 0;

Je suis à peu près sûr qu'il y a des erreurs dans ce code. Mais l'idée y est. Tout ceci dans un cron root.

Sinon, comme j'utilise OpenOffice en front, je créé dans Postgres une table Alarme avec ce dont j'ai besoin en champs, et Openoffice qui gère lui même la recherche... à creuser.

Vous avez des lumières là dessus ?

A bientôt,

LeHibou

Dernière modification par LeHibou (10/11/2010 15:19:59)

Hors ligne

#12 10/11/2010 16:54:48

Marc Cousin
Membre

Re : Trigger anniversaire

Oui, le cron c'est quelque chose de ce genre là. De préférence avec quelque chose qui laisse une trace de la dernière exécution réussie (dans une table par exemple). Pour pouvoir superviser son fonctionnement correct (il suffit, comme dit plus haut, qu'un admin décide de supprimer les crontab ou d'éteindre cron…)


Marc.

Hors ligne

#13 14/11/2010 12:13:08

LeHibou
Membre

Re : Trigger anniversaire

D'accord,

Avec la fonction de recherche interne à Postgres: il suffit de créer des champs "jour", "mois" et "année" dans la table client pour la date de naissance et de ne faire qu'une recherche sur le(s) mois concerné(s) de cette table. Cela fonctionne impeccablement.

Avec le cron, il faut penser sa stratégie : voir deux mois à l'avance pour les anniversaires est un minimum. On configure donc 6 lignes dans le crontab cherchant chaque fois le mois présent et le mois d'après.

Avec le spreadsheet, et avec l'utilisation en front d'openoffice, il suffit d'extraire la table et de faire un tri sur les résultats. Je n'ai pas essayé le data pilot (je n'aime pas sa logique de configuration).

Voilà pour faire le tour de ma question avec Postgresql 9.x.

A bientôt !

Le Hibou

Dernière modification par LeHibou (14/11/2010 12:13:48)

Hors ligne

Pied de page des forums