La valeur donnée de type String de la source de données ne peut pas être convertie en type float de la colonne cible spécifiée.

.net asp.net c# sql sqlbulkcopy

Question

Je me demandais si quelqu'un pourrait aider. J'essaie de lire un fichier CSV en C # et d'importer ses données dans un tableau que j'ai créé dans SQL 2008.

Pour une raison quelconque, je continue à avoir l'erreur suivante:

"La valeur donnée de type String de la source de données ne peut pas être convertie en type float de la colonne cible spécifiée."

Trace de pile complète:

System.Data.SqlClient.SqlBulkCopy.ConvertValue(Object value, _SqlMetaData metadata, Boolean isNull, Boolean& isSqlType, Boolean& coercedToDataFeed)
System.Data.SqlClient.SqlBulkCopy.ReadWriteColumnValueAsync(Int32 col)
System.Data.SqlClient.SqlBulkCopy.CopyColumnsAsync(Int32 col, TaskCompletionSource`1 source)
System.Data.SqlClient.SqlBulkCopy.CopyRowsAsync(Int32 rowsSoFar, Int32 totalRows, CancellationToken cts, TaskCompletionSource`1 source)
System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsyncContinued(BulkCopySimpleResultSet internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource`1 source)
System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsync(BulkCopySimpleResultSet internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource`1 source)
System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalRestContinuedAsync(BulkCopySimpleResultSet internalResults, CancellationToken cts, TaskCompletionSource`1 source)
System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalRestAsync(CancellationToken cts, TaskCompletionSource`1 source)
System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalAsync(CancellationToken ctoken)
System.Data.SqlClient.SqlBulkCopy.WriteRowSourceToServerAsync(Int32 columnCount, CancellationToken ctoken)
System.Data.SqlClient.SqlBulkCopy.WriteToServer(DataTable table, DataRowState rowState)
System.Data.SqlClient.SqlBulkCopy.WriteToServer(DataTable table)
RMBEventReportingSystemPOC.Admin.ProcessFile(String strFilename) in \Admin.aspx.cs:line 159

Veuillez trouver ci-dessous le code que j'utilise. S'il vous plaît laissez-moi savoir où je me suis trompé:

StatusLabel.Text = "File Process status: File process started!";
try
{

    //var fileName = string.Format(strFilename, Directory.GetCurrentDirectory());

    SqlConnection con = new SqlConnection(@"**ConnectionString**");

    string filepath = Server.MapPath("~/uploads/") + strFilename;
    StreamReader sr = new StreamReader(filepath);
    string line = sr.ReadLine();
    string[] value = line.Split(';');
    DataTable dt = new DataTable();
    DataRow row;
    foreach (string dc in value)
    {
        if (dc == "Month" || dc == "Year" || dc == "Reply")
            dt.Columns.Add(new DataColumn(dc, typeof(int)));
        else if (dc == "CostPerHead" || dc == "TotalCost")
            dt.Columns.Add(new DataColumn(dc, typeof(float)));
        else
            dt.Columns.Add(new DataColumn(dc));
    }

    while (!sr.EndOfStream)
    {
        value = sr.ReadLine().Split(';');
        if (value.Length == dt.Columns.Count)
        {
            row = dt.NewRow();


            //fix up default values                        
            value[1] = value[1] == "" ? "0" : value[1].ToString().Trim();
            value[2] = value[2] == "" ? "0" : value[2].ToString().Trim();
            value[3] = value[3] == "" ? "0.00" : string.Format("{0:0.00}",value[3].ToString());
            value[4] = value[4] == "" ? "0.00" : string.Format("{0:0.00}",value[4].ToString());
            value[7] = value[7] == "" ? "0" : value[7].ToString().Trim();

            row.ItemArray = value;

            dt.Rows.Add(row);
        }
    }

    ////fix up default values

    for (int i = 0; i < dt.Rows.Count; i++)
    {

        dt.Rows[i][1] = int.Parse(dt.Rows[i][1].ToString().Trim());
        dt.Rows[i][2] = int.Parse(dt.Rows[i][2].ToString().Trim());
        dt.Rows[i][3] = Math.Round(float.Parse(dt.Rows[i][3].ToString() + ".00"), 2);
        dt.Rows[i][4] = Math.Round(float.Parse(dt.Rows[i][4].ToString() + ".00"), 2);

        dt.Rows[i][7] = dt.Rows[i][7].ToString() == "" ? 0 : int.Parse(dt.Rows[i]["Reply"].ToString().Trim());
    }

    SqlBulkCopy bc = new SqlBulkCopy(con.ConnectionString, SqlBulkCopyOptions.TableLock);
    bc.DestinationTableName = "Guestlist";
    bc.BatchSize = dt.Rows.Count;
    // add column mappings if necessary               
    con.Open();
    bc.WriteToServer(dt);
    bc.Close();
    con.Close();


    StatusLabel.Text = "File Process status: File process completed! " + dt.Rows.Count.ToString() + " records imported.";
    StatusLabel.CssClass = "success";
}
catch (Exception exx)
{

    StatusLabel.Text = "File Process status: File process failed!: " + exx.Message;
    StatusLabel.CssClass = "error";
}

tout pointeur serait grandement apprécié.

Réponse acceptée

Une ou plusieurs de vos colonnes sont définies en tant que type flottant dans la base de données.

Toutefois, dans le fichier CSV, la valeur de la colonne est une chaîne ou contient une valeur qui ne peut pas être convertie en type float.

Les colonnes que vous convertissez à

dt.Rows[i][3] = Math.Round(float.Parse(dt.Rows[i][3].ToString() + ".00"), 2);
dt.Rows[i][4] = Math.Round(float.Parse(dt.Rows[i][4].ToString() + ".00"), 2);

peut contenir déjà un nombre à virgule flottante. En ajoutant ".00", vous le rendez maintenant invalide et la conversion échoue donc.

En fonction des données, supprimez la conversion ou utilisez-la de manière conditionnelle.


Réponse populaire

SqlBulkCopy.WriteToServer(DataTable) échoue avec des messages confus si l'ordre des colonnes du DataTable diffère de l'ordre des colonnes de la définition de table dans votre base de données (lorsque cela entraîne une incompatibilité de type ou de longueur). Apparemment, la méthode WriteToServer ne mappe pas les noms de colonnes.



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi