pascalrochon
Messages postés18Date d'inscriptionlundi 15 avril 2002StatutMembreDernière intervention 3 mars 2010
-
10 févr. 2007 à 17:30
pascalrochon
Messages postés18Date d'inscriptionlundi 15 avril 2002StatutMembreDernière intervention 3 mars 2010
-
11 févr. 2007 à 22:34
Bonjour, je viens d'installer Mysql car j'ai maintenant un besoin de cré de très grosse base (au moin 40gig) à partir de petit fichier dbase (dbf) (environ 2000).
Suite a une recherche sur code source et autre site web j'ai construit une petite application me permettant d'importer en batch ma série de fichier dbf dans une table mysql. Mais voila le problème c'est que je trouve l'importation très longue.
Voici donc ce que j'utilise:
deux connexion ADO, une pour mysql et une pour Dbase, ensuite je lit chacune des données et je les ajoute dans la base mysql. Voici donc la partie de mon programme qui importe les données
Set rs_mysql = New Recordset
Set rs_dbf = New Recordset
rs_mysql.Open "SELECT * FROM attribut;", conn_mysql, adOpenDynamic, adLockOptimistic
rs_dbf.Open "SELECT * FROM " & nom_dbf & ";", conn_dbf
rs_dbf.MoveFirst
Do Until rs_dbf.EOF
rs_mysql.AddNew
For Each fld In rs_dbf.Fields
rs_mysql(fld.Name) = fld.Value
Next
rs_dbf.MoveNext
rs_mysql.Update
Loop
Est-ce qu'il y aurait une autre méthode ou bien une amélioration du code qui permettrait de fair l'importation plus rapidement? N'importe quel gains de temps sera appréciable car avec la quantité de table et de données que j'ai a importer ce sera apprécié.
cs_casy
Messages postés7741Date d'inscriptionmercredi 1 septembre 2004StatutMembreDernière intervention24 septembre 201440 11 févr. 2007 à 14:43
Sans garantie de fonctionnement, tu peux peut-etre essayer une requette du style
INSERT INTO cible [(champ1[, champ2[,
...]])] [IN basededonnéesexterne]
SELECT
[source.]champ1[, champ2[, ...]
FROM
expressiontable
Depuis la table source pour chaque table, essaye la requette suivante :
INSERT INTO table_cible IN base_cible SELECT * FROM table_source
Bien sur il faut que les champs soient identiques et dans le même ordre dans les 2 tables. Sinon il faudra spécifier les différents champs dans la requette.
Je pense que ce style de requette fonctionne pour inserer tout les enregistrements d'une table en une seule passe. Il ne te reste plus qu'à boucler sur le nombre de table.
---- Sevyc64 (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
pascalrochon
Messages postés18Date d'inscriptionlundi 15 avril 2002StatutMembreDernière intervention 3 mars 2010 11 févr. 2007 à 17:17
Merci beaucoup ca semble très prometteur...
j'ai tenté plusieurs chose et je continue. mais ce que j'ai de la difficulté a comprendre c'est comment je prépare mes tables pour les inclures tout les deux dans une même requête, je m'explique:
comme dit dans mon premier message j'utilise ADO, j'ai donc deux connexion (conn_dbf et conn_mysql) .
Set rs_dbf = New Recordset
rs_dbf.Open "SELECT * FROM table_source;", conn_dbf
J'ai donc maintenant mes données à importer dans un recordset
maintenant il s'agit d'écrire la requete que tu me propose, mais c'est là que je me cogne la tête
voici donc ce que je tente
sql_insert = "INSERT INTO table_cible IN base_cible
" & rs_dbf
Set rs_mysql = conn_mysql.Execute(sql_insert)
mais ceci ne fonctionne pas du tout, ce que je n'arrive pas a comprendre c'est comment avoir mes données à importer dans le recordset qui importera les données?
je vois que j'ai quelque difficultés a comprendre l'utilisation des recordset.
pouvez-m'aider ? je me sens quelque peut bloquer (c'est peut dire..)
Merci
Pascal
PS: je tente également un autre chemin soit de créer une très grande requete du genre:
INSERT INTO table_cible values (val_1,val_2, etc...), mais ce que j'ai peur c'est que certaine table_source peuvent être très grande, donc une erreur peut plus facilement s'y glisser.. que pensez-vous de cette façon de faire?
cs_casy
Messages postés7741Date d'inscriptionmercredi 1 septembre 2004StatutMembreDernière intervention24 septembre 201440 11 févr. 2007 à 17:55
Perso j'aurais fait un code comme celui-ci :
testé sur une de mes bases sur une seule table, ça semble marcher
Dim MaConnexion As ADODB.Connection
Dim MaCommande As ADODB.Command
Set MaConnexion = New ADODB.Connection
MaConnexion.Provider = "Microsoft.Jet.oledb.4.0"
MaConnexion.Open ("Base de données
source")
Set MaCommande = New ADODB.Command
MaCommande.ActiveConnection = MaConnexion
' Partie à boucler pour chaque table
MaCommande.CommandText = "INSERT INTO
table_source IN 'Base de données cible' SELECT * FROM
table_cible"
MaCommande.Execute
' ....................................
Set MaCommande = Nothing
MaConnexion.Close
Set MaConnexion = Nothing
Bien sur ici je ne traite qu'une table. Il faut rajouter la boucle, etc....
---- Sevyc64 (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
cs_casy
Messages postés7741Date d'inscriptionmercredi 1 septembre 2004StatutMembreDernière intervention24 septembre 201440 11 févr. 2007 à 17:57
Pardon, excuse moi, il faut inverser table_source et table_cible dans le code que j'ai donné.
"INSERT INTO table_cible IN 'Base de données cible' SELECT * FROM table_source"
---- Sevyc64 (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_casy
Messages postés7741Date d'inscriptionmercredi 1 septembre 2004StatutMembreDernière intervention24 septembre 201440 11 févr. 2007 à 18:24
En imaginant que les tables existe déjà dans ta base cible et qu'elles portent exactement le même nom que dans la base source, tu pourrais faire une boucle de ce style par exemple :
' Partie à boucler pour chaque table
Dim rstSchema As ADODB.Recordset
Set rstSchema = MaConnexion.OpenSchema(adSchemaTables)
Do Until rstSchema.EOF
MaCommande.CommandText = "INSERT INTO
" & rstSchema!TABLE_NAME & " IN 'Base de données cible' SELECT * FROM " & rstSchema!TABLE_NAME
MaCommande.Execute
rstSchema.MoveNext
Loop
rstSchema.Close
Set rstSchema = Nothing
'
....................................
---- Sevyc64 (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
pascalrochon
Messages postés18Date d'inscriptionlundi 15 avril 2002StatutMembreDernière intervention 3 mars 2010 11 févr. 2007 à 21:30
Un grand merci,
j'y suis presque (enfin je pense et j'espère), il n'y a qu'une chose que je ne comprend pas très bien dans ton code, dans ta requete SQL tu as 'base de données cible', comment as-tu connecter cette base externe, parce que dans mon cas, les deux tables ne sont pas dans la même base, ni même sur le même format (dbase, mysql)
Ce que je comprend c'est que tu ouvre une connexion contenant la table à importer, ensuite tu la rend active et c'est à ce moment que tu execute ta commande sql, mais où est indiquer l'endroit où se trouve la base de données cible? c'est-à-dire la connexion à la base cible
cs_casy
Messages postés7741Date d'inscriptionmercredi 1 septembre 2004StatutMembreDernière intervention24 septembre 201440 11 févr. 2007 à 21:54
Effectivement j'avais zappé les types de bases. Moi j'ai fais les tests avec des bases access
En fait, avec cette méthode, tu n'as pas de connection à ouvrir avec le base cible. C'est, à la place de Base de données cible, que tu dois mettre le chemin d'accès à la base cible. Ensuite c'est le moteur ADO qui se charge de faire la connection.
MAintenant, effectivement je ne sais pas ce qu'il faut mettre pour une base mysql. Certainement l'adresse du serveur mais la syntaxe ???
Si je peux, je vais essayer de faire le test avec une autre base.
---- Sevyc64 (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
pascalrochon
Messages postés18Date d'inscriptionlundi 15 avril 2002StatutMembreDernière intervention 3 mars 2010 11 févr. 2007 à 22:34
J'ai regardé ce que tu m'a dit dans ton dernier message et voici ce le résultats:
Dim MaCommande As ADODB.Command
Set rs_mysql = New Recordset
Set MaConnexion = New ADODB.Connection
connexion_mysql= "DRIVER={MySQL ODBC 3.51 Driver}; SERVER=serviteur; DATABASE=pw_outaouais; UID=user; PWD=password"
Set MaCommande = New ADODB.Command
MaCommande.ActiveConnection = MaConnexion
MaCommande.CommandText = "INSERT INTO attribut IN '" & connexion_mysql & "' SELECT * FROM 13_40"
MaCommande.Execute
Le message d'erreur que je recois: il me dit qu'il ne trouve pas le fichierC:\patchwork outaouais\C_1\DRIVER={MySQL ODBC 3.51 Driver}; SERVER=serviteur; DATABASE=pw_outaouais; UID=user; PWD=password
Ce que je comprend c'est que je n'utilise pas la bonne méthode de connexion pour la base cible, est-ce que tu as une idée?