PostgreSQL
La base de données la plus sophistiquée au monde.

Ouverture de session

Navigation

Contactez-nous

Administration du site :
"equipe chez postgresqlfr point org"

Contact presse :
"fr chez postgresql point org"

Contact association :
"bureau chez postgresqlfr point org"

Questions PostgreSQL :
 IRC :
  serveur irc.freenode.net
  canal #postgresqlfr

Recherche

Accéder aux archives

« Octobre 2008  
Lun Mar Mer Jeu Ven Sam Dim
  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  

Syndication

Flux XML

Sondage

Quelle est la version de PostgreSQL la plus répandue sur vos serveurs ?
8.3
10%
8.2
42%
8.1
40%
8.0
2%
7.4
6%
7.3 ou antérieure
0%
Nombre de votes: 48

fonction postgresql

| fonction postgresql

Par alterego le 16/11/2007 - 15:39

Dans 1 table ->

create table jo_essai_systeme (
  nom_champ varchar(50),
  nb_enr numeric(6)
);

"nom_champ" contient en fait les noms des colonnes d'1 autre table.

CREATE FUNCTION jo_function_temp() RETURNS integer AS '
DECLARE
  c_nom cursor for select nom_champ from jo_essai_systeme ;
  s_nom jo_essai_systeme.nom_champ%TYPE;
  vnb numeric ;
BEGIN
  OPEN c_nom;
  LOOP
  FETCH c_nom into s_nom;
    IF NOT FOUND THEN
      EXIT;
    END IF;
    select count(s_nom) into nb from analyses where s_nom is not null ;
    update jo_essai_systeme
    set nb_enr = nb where nom_champ = s_nom ;
  END LOOP ;
 
  CLOSE c_nom ;
  RETURN 1 ;
END ;
' LANGUAGE plpgsql;

Je veux simplement compter dans nb_enr de jo_essai_systeme, pour chacun des champs de cette table, les champs de la table analyses qui sont renseignés. Est-ce que je suis clair?
ex : dans jo_essai_systeme j'ai 1 CHAMP intitulé "pretrait" et dans analyses j'ai 1 COLONNE "pretrait".
Tel que j'ai écrit la fonction, je ramène systematiquement lnb total d'enregistrements de analyses.
J'ai 1 pb de CONTENU et CONTENANT!!
merci par avance.

Options d'affichage des commentaires

Sélectionnez la méthode d'affichage des commentaires que vous préférez, puis cliquez sur "Sauvegarder les paramètres" pour activer vos changements.

HELP, je suis vraiment concé!!

alterego/ = 20 Novembre, 2007 - 14:42

svp répondre, même s'il n'y a pas de solution

Message du modérateur: merci de ne pas poster de message en double, de plus avec un sujet n'indiquant pas dans quelle catégorie rentre le problème.


Erreur

SAS/ = 20 Novembre, 2007 - 23:43

La requête

update jo_essai_systeme
set nb_enr = nb where nom_champ = s_nom ;

me semble fausse. s_nom est une chaîne de caractère et non une colonne.

Librement,
Stéphane Schildknecht
dalibo
PostgreSQLFr


fonction postgresql

alterego/ = 21 Novembre, 2007 - 12:41

c'est bien là mon problème. Cette chaine de caractère contient le nom d'1 colonne.
Cette fonction est sensée tourner même si on ajoute 1 champ à la table analyses. Pour comprendre je complète avec le début de la fonction.

create table jo_essai_systeme(nom_champ varchar(50),
nb_enr numeric(6));
insert into jo_essai_systeme(nom_champ)
select attname from pg_attribute where attrelid =
(select oid from pg_class where relname ilike 'analyses')
and attname not like 'met%';


Ma solution

sparky/ = 21 Novembre, 2007 - 13:00

Qq erreurs
1. Changer vnb par nb
2. Tu dois utiliser du sql dynamique : http://docs.postgresqlfr.org/8.1/plpgsql-statements.html
3. si s_nom est un nom de colonne,alors ton select ne fonctionnera pas, car le select into ne peut être en dynamique (pour le moment)
Donc tout code devrait être

CREATE or replace FUNCTION jo_function_temp() RETURNS integer AS
$$
DECLARE
c_nom cursor for select nom_champ from jo_essai_systeme ;
s_nom jo_essai_systeme.nom_champ%TYPE;
nb numeric ;
BEGIN
OPEN c_nom;
LOOP
FETCH c_nom into s_nom;
raise notice 'Colonne is %',s_nom;
IF NOT FOUND THEN
raise notice 'NOT FOUND';
EXIT;
END IF;
execute 'select count(*) from analyses where '||s_nom||' is not null ' into nb;
raise notice 'Nb record = %',nb;
update jo_essai_systeme set nb_enr = nb where nom_champ = s_nom ;
END LOOP ;
CLOSE c_nom ;
RETURN 1 ;
END ; $$ LANGUAGE plpgsql;

Cela fonctionne sur une 8.2


fonction postgresql

alterego/ = 21 Novembre, 2007 - 16:27

Merci pour ta réponse.
le vnb à remplacer par nb était en fait 1 erreur de recopie écran.


Et ?

SAS/ = 22 Novembre, 2007 - 10:51

Quid du reste des propositions de sparky ?

Librement,
Stéphane Schildknecht
dalibo
PostgreSQLFr


fonction postgresql

alterego/ = 23 Novembre, 2007 - 10:37

Waloo!

psql:essai_systeme.sql:10: ERROR: function jo_function_temp() does not exist
psql:essai_systeme.sql:30: ERROR: syntax error at or near "select" at character 333
psql:essai_systeme.sql:32: ERROR: function jo_function_temp() does not exist
HINT: No function matches the given name and argument types. You may need to add explicit type casts.
psql:essai_systeme.sql:34: ERROR: function jo_function_temp() does not exist
mesage d'erreur??
CREATE FUNCTION jo_function_temp() RETURNS integer AS '
DECLARE
c_nom cursor for select nom_champ from jo_essai_systeme ;
s_nom jo_essai_systeme.nom_champ%TYPE;
nb numeric ;
BEGIN
OPEN c_nom;
LOOP
FETCH c_nom into s_nom;
raise notice \'Colone is %\',s_nom;
IF NOT FOUND THEN raise notice \'NOT FOUND\'; EXIT ; END IF;
execute 'select count(*) from analyses where '||s_nom||'is not null' into nb;
raise notice \'nb record = %\',nb ;
update jo_essai_systeme
set nb_enr = nb where nom_champ = s_nom ;
END LOOP ;
CLOSE c_nom ;
RETURN 1 ;
END ;
' LANGUAGE plpgsql;

Est-ce ma version 7
qui met la pagaille?
J'en ai 1 peu ras le bol. J'ai essayé dans tous les sens!! Merci à vous


Oui j'ai bien dit = "sur ma v

sparky/ = 23 Novembre, 2007 - 11:03

Oui j'ai bien dit = "sur ma version 8.2" donc le problème maintenant c'est que tu dois adapter pour avoir qq chose qui tourne sur une 7

Cela fait longtemps que je n'ai plus utilisé une 7 mais je crois que le problème vient des guillements utiliser après as et dans la fonction dynamique voir ici
http://docs.postgresqlfr.org/7.4/plpgsql-development-tips.html


fonction postgresql

alterego/ = 23 Novembre, 2007 - 14:24

où chaîne-commande est une expression manipulant une chaîne (de type text) contenant la commande à être exécutée. Cette chaîne est littéralement donnée à manger au moteur SQL.
Notez en particulier qu'aucune substitution de variable PL/pgSQL n'est faite sur la chaîne-commande. Les valeurs des variables doivent être insérées dans la chaîne de commande lors de sa construction.
Voilà ce que j'ai trouvé dans la doc, qui laisserai supposer qu'il faut à chaque fois donner la valeur de la variable. J'ai essayé les simples ou double '', également le caractére d'échappeent. Je suis obligé de passer maintenant le bb au collègue en espérant qu'il aura + de réussite que moi. C'est pas bon pour ma promo!!
Merci à tous. Bien qu n'ayant pas eu de succés, c'est 1 forum qui a le mérite d'exister.


la soluce

sparky/ = 23 Novembre, 2007 - 18:44

execute ''select count(*) from analyses where ''||s_nom||''is not null'' into nb;

Il fallait doubler les quotes :-)


fonction postgresql

alterego/ = 26 Novembre, 2007 - 10:25

j'ai déjà essayé de doubler les quotes. Je vais encore vérifier, peut-être que j'ai
les idées + claires le matin!!


fonction postgresql

alterego/ = 26 Novembre, 2007 - 10:31

C'est fait. Voici le message d'erreur
psql:essai_systeme.sql:31: NOTICE: Colone is no_prof_base
psql:essai_systeme.sql:31: ERROR: syntax error at or near "$2" at character 76
CONTEXT: PL/pgSQL function "jo_function_temp" line 11 at execute statement


Pourquoi ne pas upgrader à l

sparky/ = 26 Novembre, 2007 - 16:12

Pourquoi ne pas upgrader à la 8 ? La 7 c'est vraiment vieux. Tu peux aussi regarder dans les logs de postgresql pour voir quelle est la requete sql reçue ...


fonction postgresql

alterego/ = 26 Novembre, 2007 - 17:22

C'est pas moi qui décide. Je ne suis que le grouillau(?) de service et je n'ai pas forcément tous les pouvoirs


Récapitulons

SAS/ = 27 Novembre, 2007 - 13:18

Pouvez-vous nous donner la dernière version de la fonction et les derniers messages d'erreur ?

Librement,
Stéphane Schildknecht
dalibo
PostgreSQLFr


fonction postgresql

alterego/ = 3 Décembre, 2007 - 11:25

DROP TABLE
CREATE TABLE
INSERT 0 152
DELETE 7
psql:essai_systeme.sql:10: ERROR: function jo_function_temp() does not exist
CREATE FUNCTION
psql:essai_systeme.sql:31: NOTICE: Colone is no_prof_base
psql:essai_systeme.sql:31: ERROR: syntax error at or near "$2" at character 76
CONTEXT: PL/pgSQL function "jo_function_temp" line 11 at execute statement
Voici l'erreur

voici la dernière version
drop table jo_essai_systeme ;
create table jo_essai_systeme(nom_champ varchar(50),
nb_enr numeric(6));
insert into jo_essai_systeme(nom_champ)
select attname from pg_attribute where attrelid =
(select oid from pg_class where relname ilike 'analyses')
and attname not like 'met%';
delete from jo_essai_systeme where nom_champ in('tableoid','cmax','cmin','xmax','xmin','oid','ctid');
DROP function jo_function_temp();
CREATE FUNCTION jo_function_temp() RETURNS integer AS '
DECLARE
c_nom cursor for select nom_champ from jo_essai_systeme ;
s_nom jo_essai_systeme.nom_champ%TYPE;
nb numeric ;
BEGIN
OPEN c_nom;
LOOP
FETCH c_nom into s_nom;
raise notice \'Colone is %\',s_nom;
IF NOT FOUND THEN raise notice \'NOT FOUND\'; EXIT ; END IF;

execute ''select count(*) from analyses where ''||s_nom||'' is not null'' into nb;
update jo_essai_systeme
set nb_enr = nb where nom_champ = s_nom ;
END LOOP ;
CLOSE c_nom ;
RETURN 1 ;
END ;
' LANGUAGE plpgsql;
-- Execution
select jo_function_temp();

Excuses, j'étais passé à autre chose ce qui fait que je n'avais pas consulté ma messagerie.
je suis en déplacement toute cette fin de semaine.


Et si on essayait ? execu

sparky/ = 3 Décembre, 2007 - 14:41

Et si on essayait ?

execute \'select count(*) from analyses where \'||s_nom||\' is not null\' into nb;

Normalement dans les log de postgresql tu peux voir quelle requête a été lancée et donc la corriger


© PostgreSQLFr, tous droits réservés.
Site déclaré à la CNIL sous le numéro 1074678, conformément à la Loi en vigueur.