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

#1 05/01/2011 21:42:53

damalaan
Membre

Passage de paramètre pour la COPY

Bonjour,

j'ai créé une fonction qui importe un fichier texte. Je voudrais passé le chemin du fichier en paramètre pour pouvoir me servir de cette fonction depuis une page web via PHP

-- Function: essais()

-- DROP FUNCTION essais();

CREATE OR REPLACE FUNCTION essais()
  RETURNS void AS
$BODY$
BEGIN

-- on efface les tables temporaires
delete from tbl_import;
delete from tbl_import2;

-- on importe le fichier
SET client_encoding TO 'LATIN1';
COPY tbl_import FROM 'C:/essai.txt'
WITH
CSV HEADER
DELIMITER ';';

.....

Merci d'avance

Hors ligne

#2 05/01/2011 21:55:24

Marc Cousin
Membre

Re : Passage de paramètre pour la COPY

On ne peut pas passer le nom de fichier en paramètre à COPY dans une fonction PL (du moins pas avec un ordre COPY statique comme vous l'avez écrit). Je présume que c'est le problème que vous avez rencontré ?

Il faut passer par un EXECUTE… donc préparer la chaîne de l'ordre SQL avant.

Quelque chose comme :

ordre_sql := 'COPY tbl_import FROM ''' || chemin || ''' WITH CSV DELIMITER '';'''
execute ordre_sql;

Les '' (deux simple quote consécutifs) permettent d'insérer un ' dans une chaîne entre quotes

Pour comprendre les ordres dynamiques, voici la doc :
http://docs.postgresql.fr/9.0/plpgsql-statements.html (paragraphe 35.9.4)


Marc.

Hors ligne

#3 05/01/2011 23:24:42

gleu
Administrateur

Re : Passage de paramètre pour la COPY

Je sens le coup venir... le chemin fournit à la commande COPY doit être un chemin local au serveur de bases de données et il faut que l'utilisateur postgres ait le droit de lire ce fichier.


Guillaume.

Hors ligne

#4 06/01/2011 18:06:22

damalaan
Membre

Re : Passage de paramètre pour la COPY

Bien sûr!!! ça va de soi smile

petite précision : ça reste interne à un réseau d'entreprise.

Hors ligne

#5 06/01/2011 21:48:29

damalaan
Membre

Re : Passage de paramètre pour la COPY

J'ai modifié ma fonction mais ça ne marche pas

CREATE OR REPLACE FUNCTION essais(text)
  RETURNS void AS
$BODY$

DECLARE
ordre_sql varchar;

BEGIN
-- on efface les tables temporaires
delete from tbl_import;
delete from tbl_temp2_tm2;

-- on importe le fichier
SET client_encoding TO 'LATIN1';


ordre_sql := 'COPY tbl_import FROM ''' || $1 || ''' WITH CSV HEADER DELIMITER '';''';
execute ordre_sql;
.....

voici le lancement de la fonction
select essais(E'C:\\v10.csv');

voici l'erreur renvoyée

ERREUR:  n'a pas pu ouvrir le fichier « C:v10.csv » pour une lecture : No such file or directory
CONTEXT:  instruction SQL « COPY tbl_import FROM 'C:\v10.csv' WITH CSV HEADER DELIMITER ';' »
PL/pgSQL function "essais" line 14 at instruction EXECUTE

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


État SQL :58P01

apparemment c'est un souci d'échappement de caractère dans le nom du fichier...

Hors ligne

#6 06/01/2011 21:57:29

damalaan
Membre

Re : Passage de paramètre pour la COPY

select essais('C:/v10.txt') fonctionne très bien

j'avais oublié que le slash fonctionnait!!

Hors ligne

#7 07/01/2011 15:03:40

Marc Cousin
Membre

Re : Passage de paramètre pour la COPY

Et surtout :
- Que l'antislash ne marche pas
- Que pour faire passer un antislash dans une chaîne il faut (sauf si standard_conforming_strings est à on, mais il est à off par défaut) le protéger par un autre \. Ce qui entraine 4 antislash au final je pense (l'antislash protégeant l'antislash, et l'antislash qui protège l'antislash protégeant l'antislash final… les joies de l'escaping smile )


Marc.

Hors ligne

#8 08/01/2011 17:09:43

damalaan
Membre

Re : Passage de paramètre pour la COPY

je suis allé jusqu'à 3 \ (au pif, c'est vrai), il m'en manquait  1 !!!
Merci pour les infos.

Hors ligne

Pied de page des forums