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

#1 30/11/2018 12:15:22

trainvapeur
Membre

problèmes avec execute

Bonjour à tous,
j'ai 2 problèmes avec EXECUTE

a priori, il ne veut pas executer une commande  RAISE NOTICE  !!

J'ai créé un curseur sur une table
  cursorigine CURSOR FOR SELECT * FROM sch.itemps;

J'ai créé un curseur qui me donne la liste des champs de cette table, en gros :
    curschamp CURSOR (poidtable oid) FOR SELECT att.attname, att.atttypid, att.attlen, att.attnum, typ.typname, typ.typlen, typ.typtype
     FROM pg_attribute att INNER JOIN pg_type typ ON att.atttypid = typ.oid
      WHERE att.attrelid = poidtable;

Avec 2 boucles FOR, j'arrive parfaitement à lister les noms des champs. mais je n'arrive pas à récupérer leur contenu.
Avec
    FOR ligne_origine IN cursorigine LOOP
       .....
         FOR unchamp IN curschamp (oidtable) LOOP

je voudrai mettre la valeur du champ courant dans une variable:
EXECUTE 'SELECT ligne_origine.' || unchamp.attname || ' INTO unevaleurnum'; ne fonctionne pas
EXECUTE 'unevaleurnum := ligne_origine.' || unchamp.attname ;  ne fonctionne pas;

Vous avez une idée ?
Merci d'avance
Jean

Hors ligne

#2 30/11/2018 12:40:29

dverite
Membre

Re : problèmes avec execute

Derrière EXECUTE il faut une requête SQL et non pas du plpgsql.

SELECT quelquechose INTO variable est du plpgsql , et variable:=valeur également.

Hors ligne

#3 30/11/2018 13:02:32

trainvapeur
Membre

Re : problèmes avec execute

vu !

mais alors sous plpgsql a-t-on la possibilité de faire une indirection ?

A+
Jean

Hors ligne

#4 30/11/2018 14:43:16

trainvapeur
Membre

Re : problèmes avec execute

je précise un peu car je ne trouve pas de solution !
sous  plpgsql, j'ai

nomtablechamp := 'ligne_origine.' || unchamp.attname;
où ligne_origine est une ligne d'un curseur qui contient des données et unchamp est une ligne d'un curseur qui contient le nom d'un champ de ligne_origine.

Donc nomtablechamp contient par exemple 'ligne_origine.indice'

Comment puis-je faire pour obtenir le contenu de ce champ ?

D'avance merci !
Jean

Hors ligne

#5 01/12/2018 15:31:23

dverite
Membre

Re : problèmes avec execute

mais alors sous plpgsql a-t-on la possibilité de faire une indirection ?

Non, plpgsql ne sait pas faire ça, pas plus que sql.
Au mieux, les fonctions telles que row_to_json() permettent de lire des jeux de résultats de manière un peu dynamique du fait du modèle collection/clef/valeur du type json,
Mais pour aller vraiment plus loin il faut passer aux langages où les noms de colonnes ne sont pas des identifiants mais des variables.

Hors ligne

#6 01/12/2018 19:00:09

Re : problèmes avec execute

dverite a écrit :

mais alors sous plpgsql a-t-on la possibilité de faire une indirection ?

Non, plpgsql ne sait pas faire ça, pas plus que sql.
Au mieux, les fonctions telles que row_to_json() permettent de lire des jeux de résultats de manière un peu dynamique du fait du modèle collection/clef/valeur du type json,
Mais pour aller vraiment plus loin il faut passer aux langages où les noms de colonnes ne sont pas des identifiants mais des variables.


Ben soit je ne comprend pas ce qu'il veut faire, soit il peut le faire avec du sql dynamique non ?

aegir=# create table toto(id integer);
CREATE TABLE
aegir=# insert into toto (select generate_series(1,1000));                                                                                  
INSERT 0 1000
aegir=# CREATE OR REPLACE FUNCTION test(text) RETURNS SETOF integer as $$
aegir$# begin return query execute( $1 ); end; $$
aegir-# LANGUAGE plpgsql;
CREATE FUNCTION
aegir=# select * from test('select id from toto limit 5');
 test 
------
    1
    2
    3
    4
    5
(5 rows)

Hors ligne

#7 02/12/2018 19:57:41

dverite
Membre

Re : problèmes avec execute

Ce qui est voulu c'est récupérer un champ variable d'une requête, donc la fonction test() serait plutôt avec une signature du style: FUNCTION test(requete text, nom_du_champ text)

Hors ligne

#8 03/12/2018 10:19:22

trainvapeur
Membre

Re : problèmes avec execute

Hervé, j'ai adapté ta solution et cela marche ... parfaitement. Sauf que c'est très long : 8 minutes pour transformer une table de 56000 lignes et 245 champs. J'ai pourtant cherché à optmiser : au lieu de traiter ligne par ligne puis champ par champ, je fais, pour chaque champ 'INSERT INTO .... SELECT monbauchamp FROM ma table;

Quand j'aurais plus le temps, je me pencherai sur JSON ...

Merci à tous
Jean

Hors ligne

Pied de page des forums