Import de données d'un SGBD à un autre

Neow26 Messages postés 50 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 12 mai 2007 - 8 mars 2006 à 00:27
Neow26 Messages postés 50 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 12 mai 2007 - 10 mars 2006 à 18:11
Salut tout le monde

Afin d'importer des données d'un SGBD à un autre (SQL Serveur à PostgreSQL), j'ai fait un petit programme d'import.
Dans ce programme j'initialise 2 connection (CnnSQL et CnnPG) et je récupère ma liste de table à importer dans une collection de type Queue (PoolTable).
J'appelle ensuite la procédure suivante afin d'importer mes données :

private
void TraiterTable(
)
{

string NomTable;

SqlDataAdapter SqlDA;

DataSet SqlDS =
new
DataSet();

OleDbDataAdapter PGDA;

while (PoolTable.Count > 0)
{
NomTable = PoolTable.Dequeue();

try
{
SqlDA =
new
SqlDataAdapter(
"Select * From " + NomTable, CnnSql);
SqlDA.Fill(SqlDS,NomTable);
PGDA =
new
OleDbDataAdapter(
"Select * From " + NomTable, CnnPG);
PGDA.Update(SqlDS, NomTable);
}

catch {}
}
}

Je n'ai aucune erreur mais aucune données n'est copiée. Je ne suis pas sur à 100% que mes structures sont équivalentes car j'ai utiliser un programme externe pour les importer.
Une suggestion pour importer la structure des tables pourraient aussi m'être utile.

Merci.

29 réponses

Arthenius Messages postés 1182 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 6 septembre 2011 14
8 mars 2006 à 09:15
qd tu creer ton dataadapter tu ne fourni pas les procedure d'update et d'insert l'erreur vient de la...

il faut definir le PGDA.InserCommand

Pour avoir une chance de faire un insert

deplus tu fais un fill d'un dataset et tu update ce meme dataset, il faudrait plutot remplir un dataset avec tes donnes SQL
parcourir ce dataset et copier les donner dans un autre dataset
et faire l'update vers prosgress de ton autre dataadapter....

<hr>Arthenius
http://blogs.developpeur.org/Arthenius/

"Ce qui ne me tue pas, me rend plus fort..."
0
Neow26 Messages postés 50 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 12 mai 2007
8 mars 2006 à 14:39
Merci pour ta réponse.

Par contre je ne connais pas très bien ADO .Net alors pourrais tu m'expliquer comment créer la commande insert sachant qu'elle change suivant la table à copier.

J'espererais que cette méthode de Update d'un dataset dans un autre DataAdapter fonctionnerait afin de m'éviter une copie ligne à ligne de mon DataSet, pas terrible en performance.
0
Arthenius Messages postés 1182 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 6 septembre 2011 14
8 mars 2006 à 15:36
de toute facon tu va etre oblige de faire un boucle pour parcourir ton premier dataset pour copier chaque element dans ton 2eme dataset

pour la requete insert je t'invite a regarder mes sources ou j'ai un exemple sur l'utilisation des dataadapter et notament un exemple avec des commande avec des parametres :)

<hr>Arthenius
http://blogs.developpeur.org/Arthenius/

"Ce qui ne me tue pas, me rend plus fort..."
0
Neow26 Messages postés 50 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 12 mai 2007
8 mars 2006 à 16:36
Sinon tant qu'on y est; il y aurait pas un moyen de reprendre simplement la strucutre de mes tables, avec les clés, index et contraintes même si possible ?
Ca m'aiderai parce que la syntaxe SQL Server et PostgreSQL c'est pas la même chose et quand y'a plus de 150 tables c'est long à tranformer.

Merci.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Arthenius Messages postés 1182 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 6 septembre 2011 14
8 mars 2006 à 16:49
le glisse deplace des tables sur un dataset....

<hr>Arthenius
http://blogs.developpeur.org/Arthenius/

"Ce qui ne me tue pas, me rend plus fort..."
0
Neow26 Messages postés 50 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 12 mai 2007
8 mars 2006 à 17:07
Bon alors je vais récapituler.
Si j'ai bien compris le mieux pour copier une nombre important de tables (structure, données, relations, clés, index et contraintes) est de remplir un 1er dataset à partir de la base d'origine puis de copier chaque table une par une dans un autre dataset lié à la base de destination.
Est-ce bien ça ou je fais une erreur ?
Si tu as la commande qui permet de copies des tables ainsi d'un dataset à un autre je suis preneur sinon je trouverai bien.

Merci pour toute ton aide.
0
Arthenius Messages postés 1182 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 6 septembre 2011 14
8 mars 2006 à 17:23
oui c ca...
voila un exemple de code qui transfert des donnees d'un dataset a l'autre :

foreach(DataRow row in ds.TS_DEPOT_VENTE.Rows)
{
if(Convert.ToBoolean(row["A_FACTURER"]))
{
DataRow newRow = ds_A_Facturer.TS_DEPOT_VENTE.NewRow();
newRow["DVNUM"] = row["DVNUM"];
newRow["FCNUM"] = row["FCNUM"];
newRow["DFCNUM"] = row["DFCNUM"];
newRow["CLNUM"] = row["CLNUM"];
newRow["ARTNUM"] = row["ARTNUM"];
newRow["DVLIG"] = row["DVLIG"];
newRow["DVART"] = row["DVART"];
newRow["DVLIB"] = row["DVLIB"];
newRow["DVQTE"] = row["DVQTE"];
newRow["DVDMP"] = row["DVDMP"];
newRow["DVDFAC"] = row["DVDFAC"];
newRow["DVFAC"] = row["DVFAC"];
ds_A_Facturer.TS_DEPOT_VENTE.Rows.Add(newRow);

}
}

<hr>Arthenius
http://blogs.developpeur.org/Arthenius/

"Ce qui ne me tue pas, me rend plus fort..."
0
Neow26 Messages postés 50 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 12 mai 2007
8 mars 2006 à 22:10
Donc après tes conseils j'en suis arrivé là :

private
void TraiterTable(
)
{

string NomTable;

while (PoolTable.Count > 0)
{
NomTable = PoolTable.Dequeue();

try
{

SqlDataAdapter SqlDA =
new
SqlDataAdapter();

DataSet SqlDS =
new
DataSet();

OleDbDataAdapter PGDA =
new
OleDbDataAdapter();

DataSet PGDS =
new
DataSet();
SqlDA.SelectCommand =
new
SqlCommand(
"Select * From " + NomTable, CnnSql);
SqlDA.Fill(SqlDS, NomTable);
PGDA.SelectCommand =
new
OleDbCommand(
"Select * From "" + NomTable +
""",CnnPG);
PGDA.Fill(PGDS, NomTable);

foreach (
DataRow row
in SqlDS.Tables[0].Rows)
{

DataRow newRow = PGDS.Tables[0].NewRow();

foreach(
DataColumn Col
in SqlDS.Tables[0].Columns)
{
newRow[Col.ColumnName] = row[Col.ColumnName];
}
PGDS.Tables[0].Rows.Add(newRow);
}
PGDA.Update(PGDS, NomTable);
}

catch (
Exception Ex) {
Console.WriteLine(Ex.Message); }
}
}

J'ai toujours une erreur sur l'update puis qu'il me manque la commande insert.
Je ne vois pas comment je peux la générer dynamiquement.
Saurez-tu me dire comment faire ?

Merci.
0
Arthenius Messages postés 1182 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 6 septembre 2011 14
9 mars 2006 à 08:59
tu ne peux pas la faire dynamiquement...

System.Data.OleDb.OleDbDataAdapter PGDA = new System.Data.OleDb.OleDbDataAdapter( "select * From " + NomTable, CnnPG);
PGDA.InsertCommand = new System.Data.OleDb.OleDbCommand("INSERT INTO "+ nomTable + " (CHAMP1, CHAMP2, CHAMP3, CHAMP4) VALUES (@VALEUR_CHAMP1, @VALEUR_CHAMP2, @VALEUR_CHAMP3, @VALEUR_CHAMP4)", CnnPG);
PGDA.InsertCommand.Parameters.Add("@VALEUR_CHAMP1", Valeur_champ1);
PGDA.InsertCommand.Parameters.Add("@VALEUR_CHAMP2", Valeur_champ2);
PGDA.InsertCommand.Parameters.Add("@VALEUR_CHAMP3", Valeur_champ1);
PGDA.InsertCommand.Parameters.Add("@VALEUR_CHAMP4", Valeur_champ4);
//et la tu pourra faire ton update...

faut te faire tout tes insert pour TOUTE tes TABLES A LA main...
pas le choix...je pense...

je ne pense pas que tu puisse faire mieux que ton foreach...

l'insert est specificaque a chacune de tes tables...
si tu a 150 table a migrer....
ben 150 insert....

apres si postgres gere les procedure stockee ca peu simplifier ton code..mais les parametre variront qd meme d'une procedure a l'autre...donc...tjs du spe...

<hr>Arthenius
http://blogs.developpeur.org/Arthenius/

"Ce qui ne me tue pas, me rend plus fort..."
0
Neow26 Messages postés 50 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 12 mai 2007
9 mars 2006 à 10:54
Est-ce que je ne pourrais pas faire un truc du genre :

string ListeChamp = "";
string ListePm = "";
foreach(DataColumn Col in SqlDS.Tables[0].Columns)
{
if (ListeChamp == "")
{
ListeChamp = Col.ColumnName;
ListePm = "@" + Col.ColumnName;
}
else
{
ListeChamp += ", " + Col.ColumnName;
ListePm += ", @" + Col.ColumnName;
}
}
PGDA.InsertCommand = new OleDbCommand("Insert Into "" + NomTable + "" (" + ListeChamp + ") values (" + ListePm + ")", CnnPG);
PGDA.Update(PGDS, NomTable);

Là j'arrive bien à générer ma commande dynamiquement mais après je comprends pas trop à quoi correspondent les paramètres ?
Pourrais-tu m'éclairer sur le sujet ?
Merci.
0
Arthenius Messages postés 1182 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 6 septembre 2011 14
9 mars 2006 à 11:13
si ca pourrait le faire...
les parametre serve a mettre a jour ta base...attend je crois que g oublie un truc...

PGDA.InsertCommand.Parameters.Add("@"+Col.ColumnName, typeof(Col.GeType()), ???la taille du champ???, Col.ColumnName);

la seul inconu reste la taille du champ

col.columnname sert de sourcecolumn qui permet de faire le lien entre le DS et la table...

<hr>Arthenius
http://blogs.developpeur.org/Arthenius/

"Ce qui ne me tue pas, me rend plus fort..."
0
Neow26 Messages postés 50 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 12 mai 2007
9 mars 2006 à 11:55
Chez moi l'instruction typeof(Col.GeType()) ne passe pas.
J'utilise un viusal studio 2005 avec un framework 2.
Est-ce un problème lié à ça ou alors une autre erreur ?

Sinon pour la taille je pourrais éventuellement allé la chercher dans les tables systemes de SQL Server mais ça devient usine à gaz.

Merci pour toute ton aide.
0
Arthenius Messages postés 1182 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 6 septembre 2011 14
9 mars 2006 à 12:04
heu GetType()...

oui il reste la solutiojn d'aller chercher dans les tables systeme....

mais la cho solution
<hr>Arthenius
http://blogs.developpeur.org/Arthenius/

"Ce qui ne me tue pas, me rend plus fort..."
0
Neow26 Messages postés 50 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 12 mai 2007
9 mars 2006 à 14:03
J'avais bien mis GetType(), c'était juste une erreur de copie et j'ai donc toujours l'erreur.

Une idée ?
0
Arthenius Messages postés 1182 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 6 septembre 2011 14
9 mars 2006 à 14:28
tu a bien mis ton col.gettype dans le foreach ??

<hr>Arthenius
http://blogs.developpeur.org/Arthenius/

"Ce qui ne me tue pas, me rend plus fort..."
0
Neow26 Messages postés 50 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 12 mai 2007
9 mars 2006 à 14:33
Voila ce que j'ai :

string ListeChamp =
"";

string ListePm =
"";

foreach(
DataColumn Col
in SqlDS.Tables[0].Columns)
{

if (ListeChamp ==
"")
{
ListeChamp = Col.ColumnName;
ListePm =
"@" + Col.ColumnName;
}

else
{
ListeChamp +=
", " + Col.ColumnName;
ListePm +=
", @" + Col.ColumnName;
}
}
PGDA.InsertCommand =
new
OleDbCommand(
"Insert Into " + NomTable +
" (" + ListeChamp +
") values (" + ListePm +
")", CnnPG);

foreach(
DataColumn Col
in SqlDS.Tables[0].Columns[0].ExtendedProperties)
{

PGDA.InsertCommand.Parameters.Add(
"@" + Col.ColumnName,
typeof(Col.GetType()), 20 , Col.ColumnName);
}
PGDA.Update(PGDS, NomTable);

J'ai mit 20 en longueur pour tester mais déjà comme ça ça se compile pas erreur sur la ligne : PGDA.InsertCommand.Parameters.Add("@" + Col.ColumnName,
typeof(Col.GetType()), 20 , Col.ColumnName);

Qu'est-ce que j'ai fait de travers ?
0
Neow26 Messages postés 50 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 12 mai 2007
9 mars 2006 à 14:35
Heu le 2ème foreach est sur foreach(DataColumn Col in SqlDS.Tables[0].Columns
) aussi.
Le reste c'était un test pour voir si je trouvais la longueur, désolé.
0
Arthenius Messages postés 1182 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 6 septembre 2011 14
9 mars 2006 à 15:08
je seche.....
je vois pas ou est le pb...dsl....

<hr>Arthenius
http://blogs.developpeur.org/Arthenius/

"Ce qui ne me tue pas, me rend plus fort..."
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
10 mars 2006 à 00:18
Salut,

Tu as fait un léger mélange là : déjà typeof sert à récupérer l'instance de System.Type caractérisant un type, et n'aurais pas fonctionner sur une instance de DataColumn.
Ensuite le type attendu par la méthode n'est pas une instance de System.Type, mais une valeur de System.Data.OledDb.OleDbType.

/*
coq
MVP Visual C#
*/
0
Neow26 Messages postés 50 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 12 mai 2007
10 mars 2006 à 00:24
Ok c'est juste ça, mais tu saurais comment passer d'un System.Type à un System.Data.OleDb.OleDbType ?
De plus tu saurais comment connâitre la longueur d'un champ ?
Merci.
0
Rejoignez-nous