2010-05-27 4 views
5

Hé là. J'ai une application C# qui analyse les fichiers txt et importe leurs données dans un db sql. J'utilisais sqlite et je travaille maintenant sur le portage vers sql server. Cela fonctionnait bien avec sqlite mais maintenant avec sql je reçois une erreur quand il traite les fichiers. Il a ajouté la première ligne de données à la base de données et a ensuite déclaré "paramètre @PartNumber a déjà été déclaré.Les noms de variables doivent être uniques dans un lot ou une procédure stockée". Voici mon code entier et la mise en page de table SQL ... l'erreur est à la dernière instance insertCommand.ExecuteNonQuery() à la fin du code ...Erreur SQL C# - Paramètre déjà défini

SQL TABLE:

CREATE TABLE Import (
    RowId int PRIMARY KEY IDENTITY, 
    PartNumber text, 
    CMMNumber text, 
    Date text, 
    FeatType text, 
    FeatName text, 
    Value text, 
    Actual text, 
    Nominal text, 
    Dev text, 
    TolMin text, 
    TolPlus text, 
    OutOfTol text, 
    FileName text 
); 

CODE:

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 = @"IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'RX_CMMData' AND TABLE_NAME = 'Import')) BEGIN SELECT DISTINCT FileName FROM Import; END"; 
        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) 
     { 


      Console.Title = "John Deere CMM Data Parser"; 
      Console.WriteLine("Preparing CMM Data Parser... done"); 
      Console.WriteLine("Scanning for new CMM data... done"); 
      Console.ForegroundColor = ConsoleColor.Gray; 

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

       con.Open(); 

       using (SqlCommand insertCommand = con.CreateCommand()) 
       { 

        SqlCommand cmdd = con.CreateCommand(); 
        string[] files = Directory.GetFiles(@"C:\Documents and Settings\js91162\Desktop\ ", "R303717*.txt*", SearchOption.AllDirectories); 



         List<string> ImportedFiles = GetImportedFileList(); 

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


         { 

          string FileNameExt1 = Path.GetFileName(file); 


          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"; 
          cmdd.Parameters.Add(new SqlParameter("@FileExt", FileNameExt1)); 

          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);"; 

           insertCommand.Parameters.Add(new SqlParameter("@FeatType", DbType.Decimal)); 
           insertCommand.Parameters.Add(new SqlParameter("@FeatName", DbType.Decimal)); 
           insertCommand.Parameters.Add(new SqlParameter("@Value", DbType.Decimal)); 
           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)); 





           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(); 

      } 
     } 
    } 
} 

Répondre

11

Essayez cette déclaration au début de la boucle foreach:

insertCommand.Parameters.Clear(); 
2

Lors de la deuxième exécution de la boucle, vous essayez à nouveau d'ajouter les paramètres à votre insertCommand, mais insertCommand est déjà instancié et contient ces paramètres.

Essayez d'ajouter tous les paramètres avant votre boucle, puis affectez la valeur à votre boucle.

5

Vous créez votre variable insertCommand une fois et vous la réutilisez à chaque fois autour de la boucle, mais vous ajoutez également les mêmes paramètres à chaque tour de la boucle. C'est pourquoi vous obtenez une erreur de paramètre en double la seconde fois qu'elle contourne la boucle.

Soit:

  • ajouter les paramètres une fois en dehors de la boucle, en gardant une référence à eux, puis définir leurs valeurs à chaque fois dans la boucle.
  • appel insertCommand.Parameters.Clear() au début de la boucle.

La première option est préférable car elle est plus efficace avec la création d'objets.

+0

Ne pas appeler Effacer(), il y a des paramètres qui seront réglés une fois, avant que la boucle - ne veux pas effacer les trop. – Blorgbeard

+0

Quelle boucle? la boucle foreach (files in files.Except ...)? –

+0

@jakesankey: Oui, cette boucle :) – Thorarin

Questions connexes