SqlBulkCopy se niega a convertir String.Empty en INT NULL

ado.net c# sqlbulkcopy sql-server-2005

Pregunta

Recientemente, se me ha asignado la tarea de crear un proceso ETL automatizado que bombee los datos a tablas basadas en el nombre plano del archivo mediante la lectura de un archivo de mapeo maestro. Decidí ir con SqlBulkCopy y todo parecía estar bien. La interfaz IDataReader se implementó para leer archivos sin formato, los metadatos de SQL Server proporcionados con el número de columnas para un mapeo de datos uno a uno, todo funcionó hasta que encontré el archivo que contenía cadenas vacías. SqlBulkCopy lanza una excepción que dice que "el valor del tipo String del origen de datos no se puede convertir al tipo int de la columna de destino especificada". Fin de la historia, ni siquiera le importa que el tipo de base de datos para esta columna sea INT NULL. Sé que puedo interpretar más los metadatos, extraer tipos de datos para columnas determinadas, crear un conjunto de datos basado en la información extraída, volver a emitir los datos de archivos planos y obtener una solución bien tipeada que funcione, pero un vago que siente que su felicidad fue brutalmente lacerada por Microsoft, o mi propia incompetencia si alguien sabe de una solución a mi repentino problema. Gracias por tu tiempo.

List<String> fileNames;

DateTime startJobTime = DateTime.Now;

Console.WriteLine("---------------------------------------------");
Console.WriteLine("Start Time: " + startJobTime);
Console.WriteLine("---------------------------------------------");

using (SqlConnection sqlCon = new SqlConnection(sqlConnection))
{
    try
    {
        sqlCon.Open();
        sqlCon.ChangeDatabase(edwDBName);

        // Get service information for staging job
        UnivStage us = GetStagingJobInfo(jobName, sqlCon);
        us.StartJobTime = startJobTime;

         // Get a list of file names
         fileNames = GetFileList(us, args);

         if (fileNames.Count > 0)
         {
              // Truncate Staging Table
              TruncateStagingTable(us, sqlCon);
              // Close and dispose of sqlCon2 connection
              sqlCon.Close();

              Console.WriteLine("Processing files: ");
              foreach (String fileName in fileNames)
                  Console.WriteLine(fileName);
              Console.WriteLine();
          }
          else
          {
              Console.WriteLine("No files to process.");
              Environment.Exit(0);
          }

          // Re-open Sql Connection
          sqlCon.Open();

          sqlCon.ChangeDatabase(stagingDBName);


          foreach (String filePath in fileNames)
          {
               using (SqlTransaction sqlTran = sqlCon.BeginTransaction())
               {
                   using (FlatFileReader ffReader = new FlatFileReader(filePath, us.Delimiter))
                   {
                       using (SqlBulkCopy sqlBulkCopy =
                                new SqlBulkCopy(sqlCon, SqlBulkCopyOptions.Default, sqlTran))
                       {
                            SqlConnection sqlCon2 = new SqlConnection(sqlConnection);

                            SetColumnList(sqlCon2, us, sqlBulkCopy);

                            sqlBulkCopy.BatchSize = 1000;
                            sqlBulkCopy.DestinationTableName =
                                us.StagingSchemaName + "." + us.StagingTableName;

                            sqlBulkCopy.WriteToServer(ffReader);

                            sqlTran.Commit();

                            sqlCon2.Close();
                        }
                    }
                }
            }

            sqlCon.ChangeDatabase(edwDBName);
            sqlCon.Close();

            sqlCon.Open();
            SetRowCount(us, sqlCon);
            sqlCon.Close();

            us.EndJobTime = DateTime.Now;
            sqlCon.Open();
            LogStagingProcess(us, sqlCon);
            sqlCon.Close();

            Console.WriteLine(us.ProcessedRowCount + " rows inserted.");

            Console.WriteLine("---------------------------------------------");
            Console.WriteLine("Success! End Time: " + us.EndJobTime);
            Console.WriteLine("---------------------------------------------");

            Console.ReadLine();
        }
        catch (SqlException e)
        {
            RenderExceptionMessagesAndExit(e,
                "Exception have occured during an attempt to utilize SqlBulkCopy\n");
        }
    }

Respuesta popular

Convierte tus cadenas vacías a DBNull .



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué