Dezipper, découper et charger du TXT dans une base

Dezipper, découper et charger du TXT dans une base - SQL/NoSQL - Programmation

Marsh Posté le 07-04-2006 à 17:45:34    

Bonjour, bonjour,  
 
je voudrais réaliser un script SQL capable des exploits suivants :
 
A la base j'ai des fichiers texte compressés (entre 7 et 8000 par semaine) qui portent un nom du type nom-date.XYZ et je voudrais fabriquer une boucle du type For Each fichier... Next (je ne connais pas la syntaxe en SQL pour ce genre d'instruction) :
 
DEZIPPER ces fichiers et les balancer dans un répertoire en leur donnant un nom du type nom-date.txt
Un fichier nom-date.txt est une succession de ligne du type :

2006021300020080AA0010000180R
          403294200001010002130206060800001
     32581702055420001010006130206061600001
     80181900223150001010012130206062520000


 
chaque chaines correspondant à un certains nombre de champs selon un découpage fixe :
 
30456783323020001010005130206061410000
donc après dézippage...
 
DECOUPAGE et CHARGEMENT des bout découpé dans une base SQL
 
vala si quelqu'un pouvait me donner la base de la syntaxe pour ça...
 
 
merci d'avance
 
a+
 
 
 
 
 
 
 

Reply

Marsh Posté le 07-04-2006 à 17:45:34   

Reply

Marsh Posté le 07-04-2006 à 21:18:12    

pour quel sgbd?

Reply

Marsh Posté le 09-04-2006 à 15:49:53    

pourquoi tout faire en sql?

Reply

Marsh Posté le 10-04-2006 à 10:10:05    

moi23372 a écrit :

pour quel sgbd?


 
 
Je tavaille sous MySQL 4.1.9 (dans la suite EasyPHP).
 
a+

Reply

Marsh Posté le 10-04-2006 à 10:25:38    

betsamee a écrit :

pourquoi tout faire en sql?


 
ah mais chui totalement open. J'avais commencé à envisager la chose sous VBA, mais je n'ai pas réussi à trouver comment passer des instructions SQL (LOAD INTO FILE, ect) en partant de VBA.
 
Et puis j'aimerais tellement traiter ça en une seule boucle...
 
Pour chaque fichier du répertoire...
1. je le dezippe
2. je l'ouvre
Pour chaque ligne du fichier...
 3. decoupage
 4. chargeage dans la base  
next
next
et finita ! :)
 
actuellement je suis obligé de créer un batch (qui dezippe) puis un SQL (qui charge) chacun long comme mon bras (autant de bloc d'instructions que de fichiers)...  
 
Et ça ne me créé qu'une table intermédiaire qui contient la chaine entière et qu'il reste à découper avec une instruction  
 
INSERT INTO table_découpée (champs1, champ2, champ3...)  
SELECT  
SUBSTRING(SUBSTRING(chaine,1,CHAR_LENGTH(chaine)-25),
SUBSTRING(chaine,CHAR_LENGTH(chaine)-24,4),
SUBSTRING(chaine,CHAR_LENGTH(chaine)-14,2),
 
etc
 
merci

Reply

Marsh Posté le 10-04-2006 à 13:46:12    

déjà le dézippage c'est pas avec SQL
 
Le forEach fichiers non plus
 
Après ca depend du SGBD
 
Mais en gros tu fais un programme qui dézippe qui fait un forEach (en DOS par exemple tu utilise la fonction for.
 
Et puis tu lance un SQL Loader ou truc du genre pour charger ton fichier
Mais tout dépend de "la marque" de ta base de données
 
Si sous Oracle faut que tu fasses un fichier de règles qui dit la longueur de tes champs (comme ce que tu as mis en couleur) et tout et tout...
 
Bonne recherche et bon courage.

Reply

Marsh Posté le 10-04-2006 à 13:47:10    

Pour MySQL fais une recherche sur loader / chargement de fichier plat...
 je ne sais pas ce qu'il existe mais ca doit bien exister... (?)

Reply

Marsh Posté le 10-04-2006 à 16:14:42    

dlaumor a écrit :

déjà le dézippage c'est pas avec SQL


 
Oui mais apparemment je peux executer du DOS depuis un script SQL...
 
[ variable = CALL ] xp_cmdshell ( chaîne [ , 'no_output' ] )
xp_cmdshell exécute une commande système, puis rend la main à l'environnement d'appel.
Le comportement par défaut des bases de données mises à niveau vers la version 8.0.2 est d'afficher le résultat. Pour les bases de données de version antérieure, un paramètre explicite d'une chaîne autre que 'no_output' peut être utilisée pour forcer le résultat à s'afficher.
 

Citation :


Le forEach fichiers non plus


 
Oui je sais, je cherche la syntaxe équivallente...
 
 

Citation :


Après ca depend du SGBD


 
MySQL 4.1.9
 
 

Citation :


Mais en gros tu fais un programme qui dézippe qui fait un forEach (en DOS par exemple tu utilise la fonction for.


 
C'est une autre solution en effet. Mais il me faut quand même pouruisvre sous SQL et il me faut de toute façon maitriser un minimum la façon d'enregistrer et d'exécuter les fichier SQL, les boucle, les déclaration de variable, etc
 

Citation :


Et puis tu lance un SQL Loader ou truc du genre pour charger ton fichier
Mais tout dépend de "la marque" de ta base de données
 
Si sous Oracle faut que tu fasses un fichier de règles qui dit la longueur de tes champs (comme ce que tu as mis en couleur) et tout et tout...


 
quand je cherche SQL loader je n'ai que des références à Oracle.
 
POur l'instant la seule chose que je sache faire, c'est executer des instructions SQL brutes (sans déclaration de variables, boucle et autre sophistication, à partir d'un fichier script que j'enregistre en .sql et que j'excute sous DOS avec l'instruction :
 
mysql -u root ma_base < chemin\mon_fichier_script.sql
 
J'ai essayé par exemple de créer un truc tout bête pour voir
 
xp_cmdshell('dir > j:\\PANEL')
 
--> err 1064
 
 
puis ça :
CREATE PROCEDURE dirpanel
BEGIN
xp_cmdshell('dir > j:\\PANEL')
END
 
 
--> pareil err 1064
 
bref, pour l'instant je nage  :cry:  
 
si quelqu'un voulait juste me mettre sur la voie, je lui baise les pieds.
 
a+

Reply

Marsh Posté le 12-04-2006 à 08:53:03    

Le SQL est un langage de requete sur une base de donnée. Et toi tu veux t'en servir pour faire d'autre type de fonction.
 
Dézippage, parcourir des répertoire et triater les fichiers de ce rtépertoire.
 
Il vaut mieux (a mon avis) faire un prg dans un langage fait pour ça (DOS...), qui appelle au moment venu une commande SQL pour faire du requettage...
 
Essayer de tout faire en SQL ne me semble pas la bonne solution.

Reply

Marsh Posté le 13-04-2006 à 14:27:50    

dlaumor a écrit :

Le SQL est un langage de requete sur une base de donnée. Et toi tu veux t'en servir pour faire d'autre type de fonction.
 
Dézippage, parcourir des répertoire et triater les fichiers de ce rtépertoire.
 
Il vaut mieux (a mon avis) faire un prg dans un langage fait pour ça (DOS...), qui appelle au moment venu une commande SQL pour faire du requettage...
 
Essayer de tout faire en SQL ne me semble pas la bonne solution.


 
merci
 
je m'oriente maintenant sur un traitement en 2 parties :
 
un .bat
un .sql (appelé par le .bat)
 
 
le seul pb c'est cette @#!!£ ! de commande echo qui me bouffe les espaces en débuts de ligne.  
 
mais de quoi je me mele !!  :cry:  
 
Pour l'instant ça donne ça. Ca marche pas encore a cause d'echo, mais je trouve que pour un n00b quasi complet en DOS y'a deux jours c'est pas mal  :o  
 
Pour la decompression j'ai laissé tombé PKUNZIP et j'utilise 7-Zip qu'est très bien :
 
@echo off
PATH %PATH% ;C :\Program Files\7-Zip
 
rem boucle de dezippage en utilisant 7Z.exe / renommage des .pnl en .pnn
for %%z in (*.PNZ) do (
7z e -ytzip -aoa %%z
ren *.pnl %%~nz.pnn)
 
rem suppression des fictemps s'ils existent
if exist fictemp0.txt del fictemp0.txt
if exist fictemp.txt del fictemp.txt
 
rem boucle de chargement
rem concatenation avec le nom du fichier et
rem chargement de la ligne dans fictemp0

for %%f in (*.pnn) do (
for /F "skip=1" %%l in (%%f) do echo %%~nf-%%l >> fictemp0.txt)
del *.pnn
 
rem reprend fictemp0 et excise la partie entre - - / supprime fictemp0
for /F "tokens=1,2,3 delims=-" %%i in (fictemp0.txt) do echo %%i;%%k >> fictemp.txt
del fictemp0.txt

echo.
echo.
echo Le fichier de concatenation des fichiers jour-debit a ete cree.
echo Debut du chargement dans la base SQL...

mysql -u root racine < chargement.sql


Message édité par Gilgamesh d'Uruk le 13-04-2006 à 17:00:50
Reply

Marsh Posté le 13-04-2006 à 14:27:50   

Reply

Marsh Posté le 13-04-2006 à 14:55:42    

Voila c'est exactement à ce genre de choses que je pensais.
 
Pour l'ECHO et les espaces, peux tu me donner une ligne exemple qui te pose prb, parce que normalement y a pas de prb

Reply

Marsh Posté le 13-04-2006 à 16:21:22    

dlaumor a écrit :

Voila c'est exactement à ce genre de choses que je pensais.
 
Pour l'ECHO et les espaces, peux tu me donner une ligne exemple qui te pose prb, parce que normalement y a pas de prb


 
les fichiers que je veux concatener ressemblent à ça :
(la première ligne est "skipée" et ensuite la boucle for /F ... echo ...>> fictemp0.txt charge le corps principal du fichier dans le fichier temporaire en ajoutant le nom du fichier au début de la ligne)
 


Nom du fichier : 124251-20051231.pnn
 
2005123100124251ON0000000000E
     32581713157070001010001311205160931000
          403315150001010002311205161000001
     84166004003550002010002311205161030000
          872483640001010004311205161100001
     32581701448650001010004311205161100001
     32581704451600001010004311205161100001
     37805688012080001010004311205161120300
     35612920601980001010005311205161140901
     50001593147320001010005311205161150000
          300248540001010006311205161400001
     87109000824030001010006311205161400001
     35612920314570001010007311205161440901
 
 
...etc.
 


 
à l'arrivée je voudrais ça :
 
 

124251-2005123-     32581713157070001010001311205160931000
124251-2005123-          403315150001010002311205161000001
124251-2005123-     84166004003550002010002311205161030000
124251-2005123-          872483640001010004311205161100001
124251-2005123-     32581701448650001010004311205161100001
124251-2005123-     32581704451600001010004311205161100001
124251-2005123-     37805688012080001010004311205161120300
124251-2005123-     35612920601980001010005311205161140901
124251-2005123-     50001593147320001010005311205161150000
124251-2005123-          300248540001010006311205161400001
124251-2005123-     87109000824030001010006311205161400001
124251-2005123-     35612920314570001010007311205161440901


 
 
Mais j'ai ça pour l'instant :
 

124251-2005123-32581713157070001010001311205160931000
124251-2005123-403315150001010002311205161000001
124251-2005123-84166004003550002010002311205161030000
124251-2005123-872483640001010004311205161100001
124251-2005123-32581701448650001010004311205161100001
124251-2005123-32581704451600001010004311205161100001
124251-2005123-37805688012080001010004311205161120300
124251-2005123-35612920601980001010005311205161140901
124251-2005123-50001593147320001010005311205161150000
124251-2005123-300248540001010006311205161400001
124251-2005123-87109000824030001010006311205161400001
124251-2005123-35612920314570001010007311205161440901


 
merci pour ton aide
 
a+
 
 
 
 
 

Reply

Marsh Posté le 13-04-2006 à 19:19:37    

Ok, j'ai géré la chose à l'aide de la fonction SUBSTRING sous SQL.
 
Bon ! bah j'ai fini wuéééééé \o/\o/\o/\o/
 
le bat :
 

@echo off
PATH %PATH% ;C :\Program Files\7-Zip
rem boucle de dezippage en utilisant 7Z.exe
rem puis renommage des date.pnl en format debit-date.pnn
for %%z in (*.PNZ) do (
7z e -ytzip -aoa %%z
ren *.pnl %%~nz.pnn)
cls
echo.
echo Fusion des fichiers jour-debit...
rem suppression des fictemps s'ils existent
if exist fictemp0.txt del fictemp0.txt
if exist fictemp.txt del fictemp.txt
rem boucle de chargement
rem concatenation avec le nom du fichier et
rem chargement de la ligne dans fictemp0
for %%f in (*.pnn) do (
for /F "skip=1" %%l in (%%f) do echo %%~nf-%%l>>fictemp0.txt)
del *.pnn
rem reprend fictemp0 et excise la partie entre - - / supprime fictemp0
rem le rajout " "%%l permet de traiter les gencod terminés par -
for /F "tokens=1,2,3,4 delims=-" %%i in (fictemp0.txt) do echo %%i;%%k %%l>>fictemp.txt
del fictemp0.txt
cls
echo.
echo Fusion des fichiers jour-debit : TERMINE
echo Chargement dans la base SQL...
rem lancement de la procédure SQL
mysql -u root xxxx< J:\PANEL\ESS\chargement.sql
rem pour finir suppression du fichier temporaire
del fictemp.txt
cls
echo.
echo Fusion des fichiers jour-debit : TERMINE
echo Chargement dans la base SQL    : TERMINE
@echo on


 
le .sql :
 
 

CREATE TABLE fictemp
(
debit int(6) unsigned NOT NULL,
chaine varchar(43) NOT NULL default ''
);
 
LOAD DATA INFILE 'J:\\PANEL\\ESS\\fictemp.txt' INTO TABLE fictemp
FIELDS TERMINATED BY ';';
 
CREATE TABLE StrESSAI
(
debit int(6) unsigned NOT NULL,
gencod bigint(18) unsigned NOT NULL,
qtt smallint(4) unsigned NOT NULL,
jj smallint(2) unsigned NOT NULL,
mm smallint(2) unsigned NOT NULL,
aa smallint(2) unsigned NOT NULL,
hh smallint(2) unsigned NOT NULL,
min smallint(2) unsigned NOT NULL,
type varchar(6) NOT NULL,
ticket mediumint(6) unsigned NOT NULL
);
 
INSERT INTO StrESSAI (debit,gencod,qtt,jj,mm,aa,hh,min,type,ticket)  
SELECT  
debit,
SUBSTRING(chaine,1,CHAR_LENGTH(chaine)-27),
SUBSTRING(chaine,CHAR_LENGTH(chaine)-26,4),
SUBSTRING(chaine,CHAR_LENGTH(chaine)-16,2),
SUBSTRING(chaine,CHAR_LENGTH(chaine)-14,2),
SUBSTRING(chaine,CHAR_LENGTH(chaine)-12,2),
SUBSTRING(chaine,CHAR_LENGTH(chaine)-10,2),
SUBSTRING(chaine,CHAR_LENGTH(chaine)-8,2),
SUBSTRING(chaine,CHAR_LENGTH(chaine)-6,5),
SUBSTRING(chaine,CHAR_LENGTH(chaine)-22,6)
FROM fictemp;
 
DROP TABLE fictemp


Message édité par Gilgamesh d'Uruk le 14-04-2006 à 12:13:30
Reply

Marsh Posté le 14-04-2006 à 10:48:01    

Content que t'ai pu t'en sortir...
 
Pour l'histoire du FOR ... ECHO ...  
J'suis pas trop expert non plus, ca doit être possible de pas perdre les espaces, peut être en utilisant des guillemets ou côte.
A voir dans la cat batch, si on peut t'aider.
 
Mais bon si ca marche avec ton SQL... ;)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed