2010-05-28 9 views
0

Aidez-moi s'il vous plaît pour cela. J'ai cette petite application pour charger des fichiers txt dans un sql db et ça marche bien avec sqlite. Quand j'ai porté sur SQL, j'ai commencé à obtenir des erreurs de "paramètre déjà déclaré". Si quelqu'un peut m'aider à réorganiser ce code, ce serait génial! Je dois obtenir les définitions des paramètres en dehors des boucles ou quelque chose ..Erreurs de paramètre SQL C# dans les boucles

using System; 
using System.Data; 
using System.Data.SQLite; 
using System.IO; 
using System.Text.RegularExpressions; 
using System.Threading; 
using System.Collections.Generic; 
using System.Linq; 
using System.Data.SqlClient; 


namespace JohnDeereCMMDataParser 
{ 
    internal class Program 
    { 


     public static List<string> GetImportedFileList() 
     { 
      List<string> ImportedFiles = new List<string>(); 
      using (SqlConnection connect = new SqlConnection(@"Server=FRXSQLDEV;Database=RX_CMMData;Integrated Security=YES")) 
      { 
       connect.Open(); 
       using (SqlCommand fmd = connect.CreateCommand()) 
       { 

        fmd.CommandText = @"SELECT FileName FROM Import;"; 
        fmd.CommandType = CommandType.Text; 
        SqlDataReader r = fmd.ExecuteReader(); 
        while (r.Read()) 
        { 
         ImportedFiles.Add(Convert.ToString(r["FileName"])); 

        } 
       } 
      } 
      return ImportedFiles; 
     } 




     private static void Main(string[] args) 
     { 




      using (SqlConnection con = new SqlConnection(@"Server=FRXSQLDEV;Database=RX_CMMData;Integrated Security=YES")) 
      { 


       con.Open(); 

       using (SqlCommand insertCommand = con.CreateCommand()) 
       { 
        Console.WriteLine("Connecting to SQL server..."); 
        SqlCommand cmdd = con.CreateCommand(); 
        string[] files = Directory.GetFiles(@"C:\Documents and Settings\js91162\Desktop\", "R.txt*", SearchOption.AllDirectories); 

        insertCommand.Parameters.Add(new SqlParameter("@FeatType", DbType.String)); 
        insertCommand.Parameters.Add(new SqlParameter("@FeatName", DbType.String)); 
        insertCommand.Parameters.Add(new SqlParameter("@Value", DbType.String)); 
        insertCommand.Parameters.Add(new SqlParameter("@Actual", DbType.Decimal)); 
        insertCommand.Parameters.Add(new SqlParameter("@Nominal", DbType.Decimal)); 
        insertCommand.Parameters.Add(new SqlParameter("@Dev", DbType.Decimal)); 
        insertCommand.Parameters.Add(new SqlParameter("@TolMin", DbType.Decimal)); 
        insertCommand.Parameters.Add(new SqlParameter("@TolPlus", DbType.Decimal)); 
        insertCommand.Parameters.Add(new SqlParameter("@OutOfTol", DbType.Decimal)); 


         List<string> ImportedFiles = GetImportedFileList(); 

         foreach (string file in files.Except(ImportedFiles)) 


         { 

          var FileNameExt1 = Path.GetFileName(file); 

          cmdd.Parameters.Add(new SqlParameter("@FileExt", FileNameExt1)); 
          cmdd.CommandText = 
           @" 
        IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'RX_CMMData' AND TABLE_NAME = 'Import')) BEGIN SELECT COUNT(*) FROM Import WHERE FileName = @FileExt; END"; 



          int count = Convert.ToInt32(cmdd.ExecuteScalar()); 
          con.Close(); 
          con.Open(); 

          if (count == 0) 
          { 
           Console.WriteLine("Parsing CMM data for SQL database... Please wait."); 


           insertCommand.CommandText = 
            @" 
        INSERT INTO Import (FeatType, FeatName, Value, Actual, Nominal, Dev, TolMin, TolPlus, OutOfTol, PartNumber, CMMNumber, Date, FileName) 
        VALUES  (@FeatType, @FeatName, @Value, @Actual, @Nominal, @Dev, @TolMin, @TolPlus, @OutOfTol, @PartNumber, @CMMNumber, @Date, @FileName);"; 






           string FileNameExt = Path.GetFullPath(file); 
           string RNumber = Path.GetFileNameWithoutExtension(file); 

           string RNumberE = RNumber.Split('_')[0]; 

           string RNumberD = RNumber.Split('_')[1]; 
           string RNumberDate = RNumber.Split('_')[2]; 

           DateTime dateTime = DateTime.ParseExact(RNumberDate, "yyyyMMdd", Thread.CurrentThread.CurrentCulture); 
           string cmmDate = dateTime.ToString("dd-MMM-yyyy"); 
           string[] lines = File.ReadAllLines(file); 
           bool parse = false; 

           foreach (string tmpLine in lines) 
           { 


            string line = tmpLine.Trim(); 
            if (!parse && line.StartsWith("Feat. Type,")) 
            { 
             parse = true; 
             continue; 
            } 
            if (!parse || string.IsNullOrEmpty(line)) 
            { 
             continue; 
            } 

            Console.WriteLine(tmpLine); 
            foreach (SqlParameter parameter in insertCommand.Parameters) 
            { 
             parameter.Value = null; 
            } 

            string[] values = line.Split(new[] { ',' }); 

            for (int i = 0; i < values.Length - 1; i++) 
            { 
             SqlParameter param = insertCommand.Parameters[i]; 
             if (param.DbType == DbType.Decimal) 
             { 
              decimal value; 
              param.Value = decimal.TryParse(values[i], out value) ? value : 0; 
             } 
             else 
             { 
              param.Value = values[i]; 
             } 
            } 



           } 

           insertCommand.Parameters.Add(new SqlParameter("@PartNumber", RNumberE)); 
           insertCommand.Parameters.Add(new SqlParameter("@CMMNumber", RNumberD)); 
           insertCommand.Parameters.Add(new SqlParameter("@Date", cmmDate)); 
           insertCommand.Parameters.Add(new SqlParameter("@FileName", FileNameExt)); 
           // 

           insertCommand.ExecuteNonQuery(); 

          } 

         } 
         Console.WriteLine("CMM data successfully imported to SQL database..."); 

        } 
        con.Close(); 

      } 
     } 
    } 
} 

Pour votre information - le PartNumber, CMMNumber, date, etc. en bas sont tirés du nom de fichier et j'ai besoin dans la table à côté de chaque enregistrement respectif.

Répondre

2

Pour vos objets de commande, vous devez faire une

insertCommand.Parameters.Clear(); 

avant de faire des

insertCommand.Parameters.Add(); 

appels. Les paramètres sont saisis lorsque vous les ajoutez à la collection. Ainsi, lorsque vous réutilisez le même objet de commande et que vous ajoutez un nouveau jeu de paramètres, les clés entrent en collision. Ou vous pouvez simplement créer un nouvel objet Command pour chaque appel, selon ce qui vous convient le mieux.

+0

Quand je fais insertCommand.Parameters.Clear(), le code s'exécute mais seule la première ligne de chaque document txt est ajoutée à la base de données .. ??? –

+0

@jake, cela ressemble à un problème avec votre looping, que vous n'aviez pas remarqué auparavant parce que votre code était erroné au début de la deuxième itération. Les paramètres.Clear() ne provoque pas l'échec de votre code, sauf si vous l'avez placé au mauvais endroit. Exécutez le code sous le débogueur et commencez à inspecter le flux de code et les valeurs des variables locales et recherchez les raisons pour lesquelles une boucle peut se terminer tôt. – slugster

+0

Le code n'échoue plus, il ne parcourt pas toutes les lignes de chaque fichier comme il le devrait. (il l'a fait avec sqlite), maintenant il se termine mais quand je vérifie la base de données, il a seulement ajouté le numéro de pièce et les données de la première ligne de chaque fichier ... affaire étrange ... faire sens? –