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

#1 05/06/2009 10:40:36

Djab
Membre

[Aide] Ecriture d'une fonction "simple"

Bonjour,

Je suis complètement nouveau dans l'utilisation de PostgreSQL (et de BD de manière général), j'aimerai mettre en place un trigger pour créer une table d'historique (h_table) d'une autre table (table).

Donc voici le code de mon trigger:

CREATE TRIGGER t_histo_table AFTER INSERT OR UPDATE
    ON table FOR EACH ROW
    EXECUTE PROCEDURE p_histo_table();

et voici la fonction associée:

CREATE OR REPLACE FUNCTION p_histo_table() RETURNS NULL AS $$
  INSERT INTO h_table (
    id,
    valeur,
    date_historique)
   SELECT
    id,
    valeur,
    sysdate
   FROM table 
   WHERE id = NEW.id;
$$ LANGUAGE SQL;

Or dans pgAdminIII quand je cherche à déclarer ma fonction (avant le trigger biensur) il me renvoie l'erreur suivante:

ERREUR:  erreur de syntaxe sur ou près de « AS »
LINE 1: ...EATE OR REPLACE FUNCTION P_HISTO_MESURE() RETURNS NULL AS $$
                                                                  ^

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

ERREUR: erreur de syntaxe sur ou près de « AS »
État SQL :42601
Caractère : 58

Est-ce que vous avez une idée de pourquoi ça ne fonctionne pas ?
Qu'elle est mon erreur de syntaxe ?
D'avance merci.

Hors ligne

#2 05/06/2009 11:20:59

gleu
Administrateur

Re : [Aide] Ecriture d'une fonction "simple"

1. NULL n'est pas un type de données, donc indiquer NULL comme paramètre du RETURNS me semble hautement suspect. D'autre part, une fonction trigger doit renvoyer le type trigger.

2. Je ne crois pas qu'il soit possible d'écrire une procédure trigger en SQL. Utilisez plutôt pl/pgsql.


Guillaume.

Hors ligne

#3 05/06/2009 12:01:36

Djab
Membre

Re : [Aide] Ecriture d'une fonction "simple"

Bonjour,

Merci pour votre réponse.
J'ai donc modifié ma fonction comme suis:

CREATE OR REPLACE FUNCTION p_histo_table() RETURNS trigger AS $$
DECLARE 
  curtime TIMESTAMP WITH TIME ZONE;
BEGIN
  INSERT INTO h_table (
    id,
    valeur,
    date_historique)
   VALUES (
    NEW.id,
    NEW.valeur,
    curtime)
  RETURN NEW;
END;
$$ LANGUAGE 'plpgsql';

Et là j'ai l'erreur:

ERREUR:  le langage « plpgsql » n'existe pas
HINT:  Utiliser CREATE LANGUAGE pour charger le langage dans la base de données.

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

ERREUR: le langage « plpgsql » n'existe pas
État SQL :42704
Astuce : Utiliser CREATE LANGUAGE pour charger le langage dans la base de données.

Ce qui est assez étrange puisque d'après la doc ce langage semble être intégré dans le gbd...
J'ai une version 8.3.7 de PostGre, et je lance mon script avec pgAdmin III 1.8.4

Hors ligne

#4 05/06/2009 12:28:25

Djab
Membre

Re : [Aide] Ecriture d'une fonction "simple"

J'ai remodifié ma requête comme ceci:

CREATE LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION P_HISTO_MESURE() RETURNS trigger AS $$
DECLARE 
  curtime TIMESTAMP WITH TIME ZONE;
BEGIN
  INSERT INTO h_mesure (
    id,
    valeur,
    date_historique)
   VALUES (
    NEW.id,
    NEW.valeur,
    curtime);
END;
$$ LANGUAGE 'plpgsql';

Et ça fonctionne (enfin) \o/.

Par contre, une question supplémentaire, doit-on à chaque script faire le CREATE LANGUAGE, ou une fois que c'est fait dans la base il n'y a plus besoin de le faire ?

Hors ligne

#5 05/06/2009 13:07:29

Marc Cousin
Membre

Re : [Aide] Ecriture d'une fonction "simple"

Une fois par base uniquement.


Marc.

Hors ligne

#6 05/06/2009 14:47:05

Djab
Membre

Re : [Aide] Ecriture d'une fonction "simple"

Marc Cousin a écrit :

Une fois par base uniquement.

A la bonne heure !

Merci beaucoup !

Hors ligne

#7 06/08/2010 16:22:15

afisse
Membre

Re : [Aide] Ecriture d'une fonction "simple"

Et que fait-on lorsque que l'on est pas super-utilisateur ? car CREATE LANGUAGE réclame ce droit

Hors ligne

#8 06/08/2010 16:27:23

Marc Cousin
Membre

Re : [Aide] Ecriture d'une fonction "simple"

On n'a pas de solution, à part demander à un super utilisateur.


Marc.

Hors ligne

#9 06/08/2010 17:11:48

baradji
Membre

Re : [Aide] Ecriture d'une fonction "simple"

Pour chaque insert ou salect, il faut utiliser une boucle for.
j'espere que ce script pourra t'aider, j'ai supprimé la requete car confidentielle.
mais n'hesite pas à me soliciter en cas de difficulté.

CREATE OR REPLACE FUNCTION fat_export_fonc(INT, "text", "text")
  RETURNS SETOF fat_export_type  AS
$BODY$
DECLARE
  mon_record fat_export_type;
BEGIN
FOR mon_record IN
EXECUTE 'SELECT ...............................................';
LOOP
RETURN NEXT mon_record ;
END LOOP;
RETURN;
END $BODY$
LANGUAGE 'plpgsql';

Hors ligne

#10 06/08/2010 17:14:49

Marc Cousin
Membre

Re : [Aide] Ecriture d'une fonction "simple"

Cela ne change rien à la question : il faut toujours avoir PLPgSQL, qui n'est pas installé par défaut. Et l'installer demande des droits super utilisateur. Ce ne sera plus le cas en 9.0, puisque plpgsql sera installé par défaut.


Marc.

Hors ligne

Pied de page des forums