Problème pour generer un script sql serveur à partir d'une base access en utilis

cs_solons Messages postés 6 Date d'inscription lundi 21 juillet 2008 Statut Membre Dernière intervention 20 août 2008 - 4 août 2008 à 10:55
cs_solons Messages postés 6 Date d'inscription lundi 21 juillet 2008 Statut Membre Dernière intervention 20 août 2008 - 4 août 2008 à 16:20
Bonjour,


Je cherche à pouvoir fabriquer un script générant une base SQL serveur
identique à une base de départ qui doit pouvoir être de plusieurs
formats (SQL serveur, Access ou excel).Seulement je n'y connais rien
(c'est pour un stage) et je ne connais ni le C# ni quoi que ce soit sur
les bases de donées. Je me suis donc tapper le site de microsoft
pendant une semaine et je me suis servi de la très bonne source qui a
été déja proposée à cet effet que vous trouverez au bout de ce lien.


Cette proposition est assez complètes mais contient quelques bugs pours
lequels je n'arrive pas à trouver de solutions et pour lesquels je
solicite votre aide.


Lorsque l'on génère un script sql serveur à partir d'une base access, le champs " AllowDBNull" est mal renseigné.

L'idée est que l'on crée une DATATABLE à partir de laquelle on
reconstruit le script permettant de généré chaque table en parcourant
la DATATABLE crée.


On utilise pour cela la commande :

oDataTableTables = oOleDbConnection.GetSchema("tables");


Pour remplir les propriétés des différentes colones on utilise le code suivant:


oOleDbDataReader = new System.Data.OleDb.OleDbCommand("SELECT * FROM ["
+ sCurrentTable + "]",
oOleDbConnection).ExecuteReader(System.Data.CommandBehavior.KeyInfo);

                        oDataTableInfosTable = oOleDbDataReader.GetSchemaTable();


                        foreach (System.Data.DataRow oDataRow in oDataTableInfosTable.Rows)

                        {

                            BObject.Column oColumn;

                            oColumn=new NET2CsExportData.BObject.Column();


                            oColumn.ColumnName = oDataRow["ColumnName"].ToString();

                          

                            oColumn.Type = this.SetDataType(oDataRow["DataType"].ToString());


                            if (oColumn.Type == "char(250)")

                            {

                                if (Convert.ToInt32(oDataRow["ColumnSize"]) > 255)

                                {

                                    oColumn.Type = "text";

                                }

                                else

                                {

                                    oColumn.Type = "char(" + Convert.ToString(oDataRow["ColumnSize"]) + ")";

                                }

                            }

                            if (Convert.ToBoolean(oDataRow["AllowDBNull"]) )

                            {

                                oColumn.isAllowDbNull = true;

                            }

                            if (Convert.ToBoolean(oDataRow["IsKey"]))

                            {

                                oColumn.isPrimaryKey = true;

                            }

                                           

                            oTable.Columns.Add(oColumn);

                        }

                        oOleDbDataReader.Close();

                        oTable.Rows = this.GetDataOfTable(oTable);

                        oTables.Add(oTable);


Quand on analyse en detail le DataRow, on se rend compte que celui-ci
n'a pas les propriétés qu'il devrait avoir. En effet si la colone sur
laquelle il travaille et une clé primaire, il le voit et la propriété
est à "true",de même la propiété "allowDBNull"est à "false". Dans tous
les autre cas enviseageables, la propiété "allowDBNull" est à "true" ce
qui pose donc un gros problème. Puisque du coup le résultat est
inutilisable.


A mon avis le problème vient de la méthode "oOleDbDataReader.GetSchemaTable()", mais je peux me tromper..


Ma question est donc autant "est ce que vous savez comment résoudre le
problème" que "est ce qu'il existe une façon de faire la mème chose
sans se servir du provider oledb (récupérer les tables sys dans access
par ex)"


Il y a un autre problème pour ceux qui peut etre connaitrait la
source.. Les Foreign key ne sont pas bien mise en place et il y a des
doublons qui rendent le script inutilisable sans l'avoir retravailler à
la main ce qui lui fait grandement perdre de son interet .. Mais je
n'ai pas encore identifier le problème donc je reposerai une question
en temps voulu.


D'avance merci.

2 réponses

yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
4 août 2008 à 15:48
Salut,
Ne connaisant pas la totalité du code les remarques suivantes ne sont peut etre pas pertinentes.

Es-tu sur de cette instruction ?

oColumn.Type = this.SetDataType(oDataRow["DataType"].ToString());

this est l'objet courrant, quel est la classe en cours ?
de plus SetDataType doit affecter un type et pas en retourner un ?
Mais je ne connais pas la classe entiere donc ...

Es-tu sur de ces 2 instructions ? (validés dans le debuger ?)
 
if (Convert.ToBoolean(oDataRow["AllowDBNull"]) )
if (Convert.ToBoolean(oDataRow["IsKey"]))

Pour etre sur, j'aurais fais :

bool bNull, bKey;
try
{
   if( oDataRow["AllowDBNull"] == null || oDataRow["IsKey"] == null )
      throw new Exception("les objets sont null");

   bNull = Convert.ToBoolean(oDataRow["AllowDBNull"]. ToString().ToLower() );
   bKey = Convert.ToBoolean(oDataRow["IsKey"].ToString().ToLower());
}
catch(Exception exc) // ou InvalidCastException
{
   throw new Exception(exc.Message);
}
0
cs_solons Messages postés 6 Date d'inscription lundi 21 juillet 2008 Statut Membre Dernière intervention 20 août 2008
4 août 2008 à 16:20
Tout d'abord, merci d'avoir pris le temps de lire ma question qui est assez indigeste j'en convient ..

pour ta première question la classe en cours s'appelle "managementaccess" et possède la méthode suivante:

private string SetDataType(string sReceived)
        {
            string sReturn;
            sReturn = string.Empty;

            if (sReceived.ToLower().IndexOf("bool") != -1)
            {
                sReturn = "bit";
            }
            if (sReceived.ToLower().IndexOf("string") != -1)
            [J'AI COUPE LE MILIEU MAIS IL Y A L'ENSEMBLE DES TYPES POSSIBLES]
            return sReturn;
        }

Pas de problème de ce coté là je pense.
Ensuite pour les instructions suivantes

if (Convert.ToBoolean(oDataRow["AllowDBNull"]) )
if (Convert.ToBoolean(oDataRow["IsKey"]))

Elles fonctionnent comme il faut .. Mais le problème est que la valeur oDataRow["AllowDBNull"] n'est pas la bonne.
Or oDataRow est initialisé par la méthode

OleDbDataReader.GetSchemaTable();

Soit la méthode fournie par Microsoft marche pas (je me rend pas du tout compte si c'est une hypothèse crédible ou pas vu que je ne connais pas les produits Microsoft) soit ... j'ai rien compris au pb
ça me semble quand même bizarre, qqun s'en serait rendu compte et ils auraient corrigé le problème..

Pourtant dès la creation de l'objet celui-ci ne contient pas les bonnes valeurs ...
La propriété "iskey" est toujours bien. Mais la propriété "AllowDBNull" n'est bonne que si la propriété "iskey" est vrai et que la colonne est une clé primaire ..

Je sais pas trop comment faire..

Il y a t'il une autre façon de récupérer ce type de propriété ??
0
Rejoignez-nous