Vous n'êtes pas identifié(e).
Bonjour,
j'ai créé une fonction qui met en place la création d'une table dans le but de récupérer plusieurs champs de différentes tables de la même base de donnée.
Puis je dois récupérer les valeurs de ces champs pour les exporter dans un fichier texte MAIS chaque fichier texte correspond à une ligne de la table crée et je dois récupérer la valeur d'un champ pour le concaténer dans le nom de ce fichier texte.
Voici le script concernant exportation dans le fichier texte :
CREATE FUNCTION nom_fonction returns text as $$
BEGIN
DROP TABLE IF EXISTS nom_table;
CREATE TABLE nom_table (numero, colonne1, colonne2);
INSERT INTO nom_table(numero, colonne1, colonne2)
SELECT champ1, champ2, champ3 from table
DECLARE
ordre_sql VARCHAR(1000);
num_id INTEGER :=1;
compteur INTEGER;
BEGIN
EXECUTE ' SELECT COUNT (numero) FROM nom_table 'INTO compteur;
WHILE (compteur <> 0)LOOP
ordre_sql :='COPY (SELECT * FROM nom_table WHERE numero = num_id LIMIT 1)
TO D:/EasyPHP-5.3.8.1/tmp/RI_AXI_0_'||id_rapport_curatif||'.txt';
num_id = num_id + 1;
compteur = compteur - 1;
END LOOP;
END;
RETURN 1;
END;
$$ language plpgsql;
Je précise que la création de la table et l'insertion des données se fait correctement mais j'ai ce message d'erreur qui s'affiche :
PL/pgSQL function "test1" line 10 at instruction SQL
ERREUR: la colonne «numero » n'existe pas
LINE 2: TO D:/EasyPHP-5.3.8.1/tmp/RI_AXI_0_'||id_rapport_cur...
^
QUERY: SELECT 'COPY (SELECT * FROM nom_table WHERE numero = num_id LIMIT 1)
TO D:/EasyPHP-5.3.8.1/tmp/RI_AXI_0_'||numero||'.txt'
CONTEXT: PL/pgSQL function "test1" line 111 at affectation
Merci d'avance pour vos suggestions.
Hors ligne
Je doute que le CREATE TABLE s'exécute correctement: il manque les types de numero, colonne1 et colonne2.
Ensuite, je doute aussi du INSERT INTO SELECT : il n'y a pas de ; à la fin.
Marc.
Hors ligne
Bonjour,
désolé j'ai tout simplement abrégé le début du script, j'ai bien un nom et un type et également le ";" à la fin du SELECT.
A partir du bloc DECLARE, le script est dans son intégralité.
Hors ligne
Il doit pourtant y avoir quelque chose avant, parce que le message est très clair: la colonne numero n'existe pas. On peut avoir la fonction en entier ?
Marc.
Hors ligne
Voici le script dans son intégralité :
create or replace function test1() returns text as $$
BEGIN
DROP TABLE IF EXISTS nom_table;
CREATE TABLE nom_table(
numero serial NOT NULL,
colonne1 character varying(56),
colonne2 character varying(20),
CONSTRAINT pk_nom_table PRIMARY KEY (numero)
)WITHOUT OIDS;
INSERT INTO nom_table ( numero,
colonne1,
colonne2)
SELECT
champ1,
champ2,
champ3
FROM table;
DECLARE
ordre_sql VARCHAR(1000);
num_id INTEGER :=1;
compteur INTEGER;
BEGIN
EXECUTE ' SELECT COUNT (*) FROM nom_table ' INTO compteur;
WHILE (compteur <> 0)LOOP
ordre_sql :='COPY (SELECT * FROM nom_table WHERE numero = num_id LIMIT 1)
TO D:/EasyPHP-5.3.8.1/tmp/RI_AXI_0_'||numero||'.txt';
num_id = num_id + 1;
compteur = compteur - 1;
id_texte = id_texte + 1;
END LOOP;
END;
RETURN 1;
END;
$$ language plpgsql;
Dernière modification par delirium (19/01/2012 15:10:10)
Hors ligne
ordre_sql :='COPY (SELECT * FROM nom_table WHERE numero = num_id LIMIT 1)
TO D:/EasyPHP-5.3.8.1/tmp/RI_AXI_0_'||numero||'.txt';
Je ne vois pas comment le TO... pourrait être interprété? Il n'y a pas de variable numero.
Ce n'est pas plutôt num_id qu'il faudrait mettre à la place de numero?
TO D:/EasyPHP-5.3.8.1/tmp/RI_AXI_0_'||num_id||'.txt';
Hors ligne
Il est bizarre ce code:
c'est vraiment «table» la table sur laquelle vous voulez faire un SELECT ? Il sert à quoi, vu que son résultat n'est stocké nulle part ? table est un mot clé réservé, il faudrait de toutes façons l'avoir entre "" pour pouvoir l'utiliser ici.
Marc.
Hors ligne
J'ai remanié le script :
create or replace function test1() returns text as $$
DECLARE
resultat text;
BEGIN
DROP TABLE IF EXISTS nom_table;
CREATE TABLE nom_table(
numero serial NOT NULL,
colonne1 character varying(56),
colonne2 character varying(20),
colonne3 integer;
CONSTRAINT pk_nom_table PRIMARY KEY (numero)
)WITHOUT OIDS;
INSERT INTO nom_table (colonne1,colonne2,colonne3)
SELECT a.champ1,a.champ2,e.champ3
FROM autre_table a
INNER JOIN encore_table e ON e.id = a.id;
DECLARE
ordre_sql VARCHAR(1000);
num_id INTEGER := 1;
compteur INTEGER;
BEGIN
EXECUTE ' SELECT COUNT (*) FROM rapport_curatif 'INTO compteur;
WHILE (compteur <> 0)LOOP
ordre_sql :='COPY (SELECT * FROM nom_table WHERE numero = num_id LIMIT 1)
TO D:/EasyPHP-5.3.8.1/tmp/RI_AXI_0_'||colonne1||'.txt';
num_id = num_id + 1;
compteur = compteur - 1;
END LOOP;
END;
RETURN resultat;
END;
$$ language plpgsql;
@Flo, non ce n'est ni "numero" et ni "num_id" que je veux concaténer dans le nom du fichier texte mais la valeur qui se trouve dans la "colonne1", est ce que je dois la déclarer de cette manière :
=======> ma_colonne1 ma_table.colonne1%TYPE ou bien c'est autre chose ?.
@Martin, j'ai renommé autrement les tables pour éviter la confusion.
Hors ligne
Ça irait plus vite pour nous avec un exemple qui permette de reproduire le problème… Là, évidemment, une fois corrigée l'erreur de syntaxe dans le create table, j'ai une erreur parce qu'autre_table n'existe pas.
Marc.
Hors ligne
J'ai remarqué que j'avais oublié d'executer la variable "ordre_sql"
DECLARE
ordre_sql VARCHAR(1000);
num_id INTEGER := 1;
compteur INTEGER;
BEGIN
EXECUTE ' SELECT COUNT (*) FROM rapport_curatif 'INTO compteur;
WHILE (compteur <> 0)LOOP
ordre_sql :='COPY (SELECT * FROM nom_table WHERE numero = num_id LIMIT 1)
TO D:/EasyPHP-5.3.8.1/tmp/RI_AXI_0_'||colonne1||'.txt';
num_id = num_id + 1;
compteur = compteur - 1;
=======>>>EXECUTE ordre_sql;
END LOOP;
END;
ET j'ai ce nouveau message d'erreur :
ERREUR: la colonne « num_id » n'existe pas
LINE 1: ...* FROM rapport_curatif WHERE numero = num_id LIM...
^
QUERY: COPY (SELECT * FROM rapport_curatif WHERE numero = num_id LIMIT 1)
TO 'D:/EasyPHP-5.3.8.1/tmp/RI_AXI_0_1.txt'
CONTEXT: PL/pgSQL function "test1" line 116 at instruction EXECUTE
Hors ligne
ET j'ai ce nouveau message d'erreur :
ERREUR: la colonne « num_id » n'existe pas
LINE 1: ...* FROM rapport_curatif WHERE numero = num_id LIM...
C'est normal car à l'intérieur de la chaine de caractères 'COPY....num_id....' , l'interpréteur plpgsql ne fait pas d'interpolation (=recherche de variable et remplacement par leur valeur).
Le code doit le faire lui-même en faisant par exemple une construction par concaténation de ce genre-là:
ordre_sql :='COPY (SELECT * FROM nom_table WHERE numero =' || num_id || ' LIMIT 1)... '
@DanielVerite
http://blog-postgresql.verite.pro/
Hors ligne
Bonjour,
merci pour ta réponse dverite, maintenant j'arrive à récupérer chaque ligne de la table qui correspond à un fichier texte.
Il me reste un point sur lequel je bloque et c'est l'intitulé de cette discussion :
récupérer la valeur d'un champ pour la concaténer dans le nom du fichier texte c'est à dire,
j'ai une table nom_table
numero | colonne1 | colonne2 | colonne3
------------------------------------------------------------------------------------------------------------
1 0-123 dupont marc
2 0-555 martin pierre
3 0-987 françois damien
et dans le script je veux faire ceci:
TO D:/EasyPHP-5.3.8.1/tmp/RI_AXI_0_'||colonne1||'.txt';
ce qui donnerai dans mon dossier tmp:
RI_AXI_0_0-123.txt
RI_AXI_0_0-555.txt
RI_AXI_0_0-987.txt
Comment définir la variable qui correspond à cette colonne1 ?
Merci d'avance.
Hors ligne
En utilisant la même méthode que dans le 36.9.4 (boucler sur les résultats d'une requête…)
http://docs.postgresql.fr/9.1/plpgsql-c … -ITERATING
Marc.
Hors ligne
J'ai enfin trouvé la solution à mon problème,
voici le script :
DECLARE
ordre_sql VARCHAR(1000);
num_id INTEGER := 1;
compteur INTEGER;
num_interv varchar(50); ------->ajouter nouvelle variable
BEGIN
EXECUTE ' SELECT COUNT (*) FROM nom_table 'INTO compteur;
WHILE (compteur <> 0)LOOP
--------nouvelle ligne ------------------
EXECUTE ' SELECT colonne1 FROM nom_table WHERE numero = '||num_id||' LIMIT 1 'into num_interv;
------------------------------------------
ordre_sql :='COPY (SELECT * FROM nom_table WHERE numero = num_id LIMIT 1)
TO D:/EasyPHP-5.3.8.1/tmp/RI_AXI_0_'||num_interv||'.txt''DELIMITER '';''';
num_id = num_id + 1;
compteur = compteur - 1;
EXECUTE ordre_sql;
END LOOP;
END;
END;
Comment faire pour mettre "résolu" à cette discussion ?
Hors ligne
Comment faire pour mettre "résolu" à cette discussion ?
Ce n'est pas possible avec cette version de FluxBB.
Guillaume.
Hors ligne