Transfert de base de données [Résolu]

mornaloce 53 Messages postés lundi 17 mars 2008Date d'inscription 21 mars 2014 Dernière intervention - 16 janv. 2012 à 17:17 - Dernière réponse : mornaloce 53 Messages postés lundi 17 mars 2008Date d'inscription 21 mars 2014 Dernière intervention
- 7 févr. 2012 à 15:37
Bonjour à tous,

Voilà j'ai un problème. Je vous explique :
Dans l'entreprise ou je travail il y a une bdd sur le serveur principal (en PostGreSQL) et j'ai une base en local sur mon PC (en Access). Mon boss souhaite que je créé un programme qui fasse la mise à jour de la base principal via la base en local.
Pour cette mise à jour il y a deux étapes :
1 - Les deux bases étant exactement les même on commence par supprimer toutes les données des tables de la base principal. (Jusque là pas de problème)
2 - Ensuite je vais copier toutes les données de ma base en local dans la base principal et ceci table par table (via un INSERT INTO... SELECT * FROM...)

Bon ces deux étapes je peux pas faire autrement. Mon problème viens du fait que je fais mon programme en VB.Net sous visual studio et qu'il m'est impossible de faire la deuxième étapes vu que mes 2 bases sont sur des serveurs différents. J'ai chercher pendant un bout de temps sur google mais les quelques rares solutions proposées ne m'ont pas parut satisfaisantes. Quelqu'un aurait-il une idée pour m'aider à faire mon INSERT ?

Voilà. J'espère avoir été suffisamment clair dans mes explications.
Merci d'avance.
Afficher la suite 

Votre réponse

11 réponses

Meilleure réponse
cs_Jack 14010 Messages postés samedi 29 décembre 2001Date d'inscription 28 août 2015 Dernière intervention - 17 janv. 2012 à 15:45
3
Merci
Non, tu ne pourrais faire tout d'un seul coup si les deux DB étaient des bases Access locales (*), mais là, ce n'est pas possible.

Reprenons.
Si tu as deux bases de donnes, il te faudra deux connexions.
n°1 pour Access local
n°2 pour PostGreSQL distant

Pour transférer les données de 1 vers 2, il te faudra :
- remplir un RecordSet (objet ADODB recommandé) avec les données de la connexion 1. Un simple Select suffit, ou même charger toute la table dans le RecordSet.
- puis injecter les données de ce RecordSet vers la connexion 2 au travers d'une boucle de "Insert Into" pour chaque item de ce RecordSet, agrémenté optionnellement d'une gestion de transaction si tu veux être plus rapide.
Dans un premier temps, pour la mise ou point, ne t'occupe pas des transactions - cela peut se rajouter sans difficulté plus tard.

Refaire la même chose pour chaque table.

(*) avec une syntaxe ressemblant à cela :
Insert Into maTableAccess1
      (Champ1, Champ2, ..., ChampX)
Select Champ1, Champ2, ..., ChampX
  From maTableAccess2 In 'C:\mon répertoire\maBase2.MDB'

Merci cs_Jack 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 96 internautes ce mois-ci

Commenter la réponse de cs_Jack
cs_Jack 14010 Messages postés samedi 29 décembre 2001Date d'inscription 28 août 2015 Dernière intervention - 16 janv. 2012 à 18:24
0
Merci
Salut

"Mon problème viens du fait que je fais mon programme en VB.Net sous visual studio et qu'il m'est impossible de faire la deuxième étapes vu que mes 2 bases sont sur des serveurs différents"
Pourquoi problème ?
Tu n'as pas de cable/liaison entre ces deux serveurs ?
Parce que se connecter à des bases distantes n'est pas un problème en lui-même.

Je ne connais pas PostGreSQL, mais si ce gestionnaire a des outils (d'après ce que j'ai lu, oui) et vu qu'il ne s'agit que d'une migration/manipulation unique, je regarderai comment exporter les données depuis Access dans un format que PostGreSQL accepterait, genre CSV.
Faire de la programmation pour ça me parait une perte de temps.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Commenter la réponse de cs_Jack
mornaloce 53 Messages postés lundi 17 mars 2008Date d'inscription 21 mars 2014 Dernière intervention - 17 janv. 2012 à 09:48
0
Merci
Bonjour jack. Je suis plutôt d'accord avec toi il n'y a pas de vrai raisons de programmer mais ce n'est pas moi qui décide. ^^ Jusqu'à maintenant mon boss passait justement par Access mais il ne trouve pas ça très propre de faire des maccro pour maitre à jour la base principal. Du coup je dois programmer un truc. Mais jusqu'à maintenant j'ai eu beaucoup de mal à trouver comment faire.
Commenter la réponse de mornaloce
cs_Jack 14010 Messages postés samedi 29 décembre 2001Date d'inscription 28 août 2015 Dernière intervention - 17 janv. 2012 à 11:43
0
Merci
Je repose ma question :
"qu'il m'est impossible de faire la deuxième étapes vu que mes 2 bases sont sur des serveurs différents"
Pourquoi ?
C'est matériel ou bien tu ne sais pas le faire ?

Se connecter à une base distante n'est qu'une affaire de paramétrage de la connexion, ensuite, l'accès aux tables, au SQL, tout ça est identique (si le moteur est au standard SQL).
Voir <ce site de référence> en matière de connexion.

Si tu utilises ADO et que tu trouves que les Insert Into ligne à ligne est lent, regarde du côté des transactions (voir l'aide) :
-1- pour initier la transaction : maConnexion.BeginTrans
-2- tu fais une centaine d'insertion qui vont rester buffurisées
-3- Pour déclencher le transfert : maConnexion.CommitTrans
ou, pour annuler les actions buffurisées : maConnexion.RollbackTrans
Commenter la réponse de cs_Jack
mornaloce 53 Messages postés lundi 17 mars 2008Date d'inscription 21 mars 2014 Dernière intervention - 17 janv. 2012 à 14:04
0
Merci
Hé bien ça m'était impossible car il faut faire un :
requeteSqlInsert = "INSERT INTO table1SQL SELECT * FROM table1Access;"
commandSql.CommandText = requeteSqlInsert
commandSql.Connection = connexionSQL

hors ça ne me connecte qu'à SQL. Le programme ne trouvera pas la table1Access de cette manière.

J'ai voulu faire d'abord un select de mes données de table1Access que je stockait dans un tableau et que j'inserrai dans ma table1SQL via un INSERT INTO mais c'est trop long. Surtout que j'ai une dizaine de table à transférer.

Du coup pour bien répondre à ta question : oui je ne sais pas faire.
Commenter la réponse de mornaloce
mornaloce 53 Messages postés lundi 17 mars 2008Date d'inscription 21 mars 2014 Dernière intervention - 17 janv. 2012 à 20:45
0
Merci
Merci beaucoup pour ton aide jack. J’essaierais ça lundi et je te tiendrais au courant !

Encore merci !
Commenter la réponse de mornaloce
mornaloce 53 Messages postés lundi 17 mars 2008Date d'inscription 21 mars 2014 Dernière intervention - 23 janv. 2012 à 15:46
0
Merci
Bonjour,

Bon jack j'ai essayé ta méthode mais j'ai du mal à comprendre comment fonctionne le RecordSet du coup ça ne fonctionne pas.
Je t'envoie mon conde pour que tu puisse m'aider à comprendre ce qui ne fonctionne pas.

Dim connexionSQL As New NpgsqlConnection
Dim commandSQL As New NpgsqlCommand
Dim requeteSqlDelete As String = ""
Dim requeteSqlInsert As String = ""
Dim listeTablesMaj As ArrayList = New ArrayList
Dim i As Integer = 0

listeTablesMaj.Add("table1")
...

'Connexion à la base de donnée SQL
connexionSQL.ConnectionString = "Server=server;Port=port;Database=database;User ID=user;Password=pwd;"

Try
connexionSQL.Open()

'Exécution de la requête de vidage des tables
For Each table In listeTablesMaj
requeteSqlDelete = "DELETE FROM " + table + ";"

commandSQL.CommandText = requeteSqlDelete 'pour interroger la table (connexion au préalable).
commandSQL.Connection = connexionSQL
commandSQL.ExecuteNonQuery()

Next

connexionSQL.Close()

Dim connectionAccess As New ADODB.Connection
Dim recordSet As New ADODB.Recordset

connectionAccess.ConnectionString = "provider=provider;data source=" + Me.TextBox_Parcourir.Text + ";"

connectionAccess.Open()
listeTablesMaj.Reverse()
connexionSQL.Open()

'Exécution de la requête de remplissage des tables
For Each tableMaj In listeTablesMaj
recordSet.Open("SELECT * FROM " + tableMaj + ";", connectionAccess)

While Not recordSet.EOF
requeteSqlDelete = "INSERT INTO " + tableMaj -> LA JE SAIS PAS TROP QUOI METTRE
'requeteSqlDelete = "INSERT INTO " + tableMaj + "(id, statut) VALUES(" + recordSet.Fields(0).Value + ", """ + recordSet.Fields(1).Value + """;"

commandSQL.CommandText = requeteSqlDelete 'pour interroger la table (connexion au préalable).
commandSQL.Connection = connexionSQL
commandSQL.ExecuteNonQuery()
End While

recordSet.Close()

Next

connectionAccess.Close()
connexionSQL.Close()

Catch ex As Exception
Me.Label1.Text = ex.Message
Exit Sub
End Try
Commenter la réponse de mornaloce
mornaloce 53 Messages postés lundi 17 mars 2008Date d'inscription 21 mars 2014 Dernière intervention - 24 janv. 2012 à 09:57
0
Merci
Finalement j'ai trouvé une methode. Je ne sais pas si c'est la meilleur mais elle marche apparemment. Si quelqu'un en a une meilleure à proposer je prend ^^

Voilà mon code :

For Each tableMaj In listeTablesMaj
recordSet.Open("SELECT * FROM " + tableMaj + ";", connectionAccess)

For i = 0 To recordSet.Fields.Count - 1 Step 1
If (i = 0) Then
champsName = recordSet.Fields(i).Name
Else
champsName = champsName + ", " + recordSet.Fields(i).Name
End If
Next

While Not recordSet.EOF
For i = 0 To recordSet.Fields.Count - 1 Step 1
If (i = 0) Then
champsValue = recordSet.Fields(i).Value.ToString()
Else
champsValue = champsValue + ", " + recordSet.Fields(i).Value.ToString()
End If
Next

requeteSqlInsert = "INSERT INTO " + tableMaj + " (" + champsName + ") VALUES(" + champsValue + ");"

commandSQL.CommandText = requeteSqlInsert 'pour interroger la table (connexion au préalable).
commandSQL.Connection = connexionSQL
commandSQL.ExecuteNonQuery()

recordSet.MoveNext()
End While

recordSet.Close()
Next

Il ne me reste qu'à testé sur toute les tables et éventuellement utiliser les transactions.
Commenter la réponse de mornaloce
mornaloce 53 Messages postés lundi 17 mars 2008Date d'inscription 21 mars 2014 Dernière intervention - 24 janv. 2012 à 15:35
0
Merci
Bon j'ai testé. Ca fonctionne mais je me suis aperçut que j'ai des tables qui ont des colonnes en plus dans Access. Du coup ma méthode est pas adaptée. Qulqu'un à une idée s'il vous plaît ?
Commenter la réponse de mornaloce
nabil1970 6 Messages postés mardi 24 janvier 2012Date d'inscription 19 juin 2013 Dernière intervention - 24 janv. 2012 à 18:57
0
Merci
Je dois donc récupérer la base de données DBF existant sur excel mais je n arrive pas 1 j'ai converti en dbf bref je n arrive à l importer vers windev 14 .... svp comment faire pour surmonter ces erreurs je travail sur windev14
Commenter la réponse de nabil1970
mornaloce 53 Messages postés lundi 17 mars 2008Date d'inscription 21 mars 2014 Dernière intervention - 7 févr. 2012 à 15:37
0
Merci
Bon j'ai finalement réussi tout fonctionne ! Là où le transfert se faisait en 4 ou 5h avec une ancienne appli en windev, je met 2min35 avec la mienne ^^

Voilà mon code pour ceux que ça pourrait aider :

'Liste des tables à mettre à jour
listeTablesMaj.Add("table1")
listeTablesMaj.Add("table2")
...

'Connexion à la base de donnée SQL
connexionSQL.ConnectionString = "Server=server;Port=port;Database=db;User ID=user;Password=pass;"

Try
connexionSQL.Open()

'Exécution de la requête de vidage des tables
For Each table In listeTablesMaj
requeteSqlDelete = "DELETE FROM " + table + ";"

commandSQL.CommandText = requeteSqlDelete 'pour interroger la table (connexion au préalable).
commandSQL.Connection = connexionSQL 'connexion à la bdd
commandSQL.ExecuteNonQuery() 'execution de la requête SQL

Next

connexionSQL.Close()

Dim connectionAccess As New ADODB.Connection 'OleDbConnection
Dim recordSet As New ADODB.Recordset
Dim champsName As String = ""
Dim champsValue As String = ""
Dim champsValueModif As String = ""

connectionAccess.ConnectionString = "provider=microsoft.jet.oledb.4.0;data source=" + Me.TextBox_Parcourir.Text + ";"

connectionAccess.Open()
listeTablesMaj.Reverse() 'On inverse l'odre des tables dans la liste pour eviter les problèmes de dépendance
connexionSQL.Open()

Me.Label1.Text = "Début du transfert"

'///////Exécution de la requête de remplissage des tables////////

'Pour chaque table
For Each tableMaj In listeTablesMaj
recordSet.Open("SELECT * FROM " + tableMaj + ";", connectionAccess) 'Remplissage du recordSet avec toutes
les données de la table en cours dans Access

champsName = ""
champsValue = ""
champsValueModif = ""

Me.Label1.Text = tableMaj

'Récupération du nom des colonnes
For i = 0 To recordSet.Fields.Count - 1 Step 1
If i = 0 Then
champsName = recordSet.Fields(i).Name
Else
champsName = champsName + ", " + recordSet.Fields(i).Name
End If
Next

While Not recordSet.EOF

'Récupération des valeurs de la ligne en cours
For i = 0 To recordSet.Fields.Count - 1 Step 1
If i = 0 Then 'Si c'est la première valeur
If recordSet.Fields(i).Value.ToString = "" Then 'Si valeur null
champsValue = champsValue + ", NULL" 'on envoie NULL dans la requête d'insertion PostGreSQL
ElseIf Not IsNumeric(recordSet.Fields(i).Value) Then 'Si la valeur n'est pas un nombre
If recordSet.Fields(i).Value.ToString().Contains("'") Then 'Si la valeur text contient des (')
champsValueModif = Replace(recordSet.Fields(i).Value.ToString(), "'", "''") 'on double les apostrophe pour les "échapper" dans la requête
champsValue = "'" + champsValueModif + "'" 'et on ajoute des (') de chaque coté de la valeur dans la requête
Else
champsValue = "'" + recordSet.Fields(i).Value.ToString() + "'" 'Sinon on ajoute des (') de chaque coté de la valeur dans la requête
End If
Else
champsValue = recordSet.Fields(i).Value.ToString() 'Sinon on ajoute le nombre telquel dans la requete
End If
Else
If recordSet.Fields(i).Value.ToString = "" Then
champsValue = champsValue + ", NULL"
ElseIf IsDate(recordSet.Fields(i).Value) Then
champsValueModif = Format(recordSet.Fields(i).Value, "yyyy-MM-dd")
champsValue = champsValue + ", '" + champsValueModif + "'"
ElseIf Not IsNumeric(recordSet.Fields(i).Value) Then
If recordSet.Fields(i).Value.ToString().Contains("'") Then
champsValueModif = Replace(recordSet.Fields(i).Value.ToString(), "'", "''")
champsValue = champsValue + ", '" + champsValueModif + "'"
Else
champsValue = champsValue + ", '" + recordSet.Fields(i).Value.ToString() + "'"
End If
Else
champsValue = champsValue + ", " + recordSet.Fields(i).Value.ToString()
End If
End If
Next

requeteSqlInsert = "INSERT INTO " + tableMaj + " (" + champsName + ") VALUES(" + champsValue + ");" 'La requete SQL qui va servir à remplir la table dans PostGreSQL

commandSQL.CommandText = requeteSqlInsert 'pour interroger la table (connexion au préalable).
commandSQL.Connection = connexionSQL
commandSQL.ExecuteNonQuery()

recordSet.MoveNext() 'Positionnement su la ligne suivante du recordSet
End While

recordSet.Close()

Next
Me.Label1.Text = "Transfert terminé !"

connectionAccess.Close()
connexionSQL.Close()

Catch ex As Exception
MsgBox(ex.Message)
End Try
Commenter la réponse de mornaloce

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.