데이터 소스의 String 유형의 지정된 값을 지정된 대상 열의 float 유형으로 변환 할 수 없습니다.

.net asp.net c# sql sqlbulkcopy

문제

누군가가 도울 수 있는지 궁금 해서요. 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";
}

모든 포인터 크게 감사하겠습니다.

수락 된 답변

하나 이상의 열이 데이터베이스에서 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);

이미 부동 소수점 숫자를 포함 할 수 있습니다. ".00"을 추가하면 현재 유효하지 않으므로 변환이 실패합니다.

데이터에 따라 변환을 제거하거나 조건부로 사용하십시오.


인기 답변

SqlBulkCopy.WriteToServer(DataTable)DataTable 의 열 순서가 데이터베이스의 테이블 정의의 열 순서와 다른 경우 (유형 또는 길이 비 호환성이 발생할 때) 혼란스러운 메시지로 인해 실패합니다. 분명히 WriteToServer 메서드는 열 이름을 매핑하지 않습니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.