2010-05-27 18 views
5

Hola. Tengo una aplicación C# que analiza archivos txt e importa los datos de ellos en un archivo sql db. Estaba usando sqlite y ahora estoy trabajando en portarlo al servidor sql. Funcionaba bien con sqlite pero ahora con sql recibo un error cuando procesa los archivos. Agregó la primera fila de datos a la base de datos y luego dice "parameter @PartNumber ya se ha declarado. Los nombres de las variables deben ser únicos dentro de un lote o procedimiento almacenado". Aquí está toda mi código de diseño y SQL mesa ... el error se produce en el último insertCommand.ExecuteNonQuery() ejemplo, al final del código ...Error SQL C# - Parámetro ya definido

TABLE SQL:

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

CÓDIGO:

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

      } 
     } 
    } 
} 

Respuesta

11

probar este comunicado al inicio del bucle foreach:

insertCommand.Parameters.Clear(); 
2

La segunda vez en el bucle, intenta agregar los parámetros a su InsertCommand nuevamente, pero insertCommand ya está instanciado y contiene esos parámetros.

Intente agregar todos los parámetros antes de su ciclo y luego asigne el valor en su ciclo.

5

Está creando su variable insertCommand una vez y reutilizándola cada vez que pasa el ciclo, pero también le agrega los mismos parámetros cada vez que pasa el ciclo. Es por eso que obtiene un error de parámetro duplicado la segunda vez que da la vuelta al ciclo.

O bien:

  • añadir los parámetros una vez fuera del bucle, manteniendo una referencia a ellos, y después la fijación de sus valores cada vez a través del bucle.
  • llame al insertCommand.Parameters.Clear() al inicio del ciclo.

La primera opción es mejor, ya que es más eficiente con la creación de objetos.

+0

No llamar Clear(), hay algunos parámetros que se ajustan una vez, antes del bucle - no quiero borrar los mismos. – Blorgbeard

+0

¿Qué loop? el bucle foreach (archivos en archivos. Excepto ...)? –

+0

@jakesankey: Sí, ese bucle :) – Thorarin

Cuestiones relacionadas