我想知道是否有人可以提供帮助。我试图在C#中读取CSV文件并将其数据导入我在SQL 2008中创建的表中。
出于某种原因,我不断收到以下错误:
“数据源中String类型的给定值不能 转换为指定目标列的float类型。“
完成堆栈跟踪:
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
请在下面找到我正在使用的代码。请让我知道我哪里出错:
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";
}
任何指针都会非常感激。
答案 0 :(得分:3)
SqlBulkCopy.WriteToServer(DataTable)
的列顺序与数据库中表定义的列顺序不同(如果这会导致类型或长度不兼容),则 DataTable
会因混淆消息而失败。显然,WriteToServer
方法不会映射列名。
答案 1 :(得分:1)
您的一个或多个列在数据库中定义为float类型。
但是,在CSV文件中,列值是字符串或包含无法转换为浮点类型的值。
您要转换的列
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);
可能已包含浮点数。通过附加&#34; .00&#34;你现在使它无效,因此转换失败。
根据数据,删除转换或有条件地使用它。
答案 2 :(得分:0)
对于名为value的变量,您应该使用对象数组而不是字符串数组。
然后对您分配给它的任何数据调用Convert.ToFloat()方法,该数据最终会在数据库的float列中结束。
当你将对象数组设置为row.ItemArray时,数据库中浮动的字段也会在你的数组中浮动,你应该可以提交到数据库了。