C# 关于数据类型的异常

C# 关于数据类型的异常,c#,sql,sql-server,visual-studio,datagridview,C#,Sql,Sql Server,Visual Studio,Datagridview,我已经创建了一个应用程序,其中有一个datagridview。当我单击一个按钮时,写入datagridview的数据将以表的形式发送到我的数据库。但我有个例外,我迷路了 错误:System.Data.SqlClient.SqlException:“无法将nvarchar值“B003382A3”转换为int值。” 我甚至不知道他为什么试图转换成int,因为我的数据库中的数据是nvarchar。我唯一的建议是他正在转化细胞 我的代码: private void metroButton1_Click(

我已经创建了一个应用程序,其中有一个datagridview。当我单击一个按钮时,写入datagridview的数据将以表的形式发送到我的数据库。但我有个例外,我迷路了

错误:System.Data.SqlClient.SqlException:“无法将nvarchar值“B003382A3”转换为int值。”

我甚至不知道他为什么试图转换成int,因为我的数据库中的数据是nvarchar。我唯一的建议是他正在转化细胞

我的代码:

private void metroButton1_Click(object sender, EventArgs e)
{
    SqlConnection maConnexion = new SqlConnection("Server= localhost; Database= Seica_Takaya;Integrated Security = SSPI; ");
    maConnexion.Open();

    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        if ((row.Cells[20].Value != null) && (bool)row.Cells[20].Value)
        {
            SqlCommand command = maConnexion.CreateCommand();

            command = new SqlCommand("update FailAndPass set Machine=@machine, ProgCode=@pc, BoardName=@BName, BoardNumber=@BNumber, Tester=@T, DateTest=@DT, TimeTest=@TT, TimeStart=@TS, FComponent=@FC, Message=@Mess, TotalTestProg=@TTP, ReadValue=@RV, ValueReference=@VR, PTolerance=@PT, FaultCodeByOP=@FCBO, FaultDetail=@FD,  RepairingDate=@RD, RepairingTime = @RT, ReportingOperator=@RO WHERE SerialNum=@Serial", maConnexion);
            command.Parameters.AddWithValue("@Serial", textBox1.Text);
            command.Parameters.AddWithValue("@Machine", row.Cells[0].Value != null ? row.Cells[0].Value : DBNull.Value);
            command.Parameters.AddWithValue("@pc", row.Cells[2].Value != null ? row.Cells[2].Value : DBNull.Value);
            command.Parameters.AddWithValue("@BName", row.Cells[3].Value != null ? row.Cells[3].Value : DBNull.Value);
            command.Parameters.AddWithValue("@BNumber", row.Cells[4].Value != null ? row.Cells[4].Value : DBNull.Value);
            command.Parameters.AddWithValue("@T", row.Cells[5].Value != null ? row.Cells[5].Value : DBNull.Value);
            command.Parameters.AddWithValue("@DT", row.Cells[6].Value != null ? row.Cells[6].Value : DBNull.Value);
            command.Parameters.AddWithValue("@TT", row.Cells[7].Value != null ? row.Cells[7].Value : DBNull.Value);
            command.Parameters.AddWithValue("@TS", row.Cells[8].Value != null ? row.Cells[8].Value : DBNull.Value);
            command.Parameters.AddWithValue("@FC", row.Cells[9].Value != null ? row.Cells[9].Value : DBNull.Value);
            command.Parameters.AddWithValue("@Mess", row.Cells[10].Value != null ? row.Cells[10].Value : DBNull.Value);
            command.Parameters.AddWithValue("@TTP", row.Cells[11].Value != null ? row.Cells[11].Value : DBNull.Value);
            command.Parameters.AddWithValue("@RV", row.Cells[12].Value != null ? row.Cells[12].Value : DBNull.Value);
            command.Parameters.AddWithValue("@VR", row.Cells[13].Value != null ? row.Cells[13].Value : DBNull.Value);
            command.Parameters.AddWithValue("@PT", row.Cells[14].Value != null ? row.Cells[14].Value : DBNull.Value);
            command.Parameters.AddWithValue("@FCBO", row.Cells[15].Value != null ? row.Cells[15].Value : DBNull.Value);
            command.Parameters.AddWithValue("@FD", row.Cells[16].Value != null ? row.Cells[16].Value : DBNull.Value);
            command.Parameters.AddWithValue("@RD", row.Cells[17].Value != null ? row.Cells[17].Value : DBNull.Value);
            command.Parameters.AddWithValue("@RT", row.Cells[18].Value != null ? row.Cells[18].Value : DBNull.Value);
            command.Parameters.AddWithValue("@RO", row.Cells[19].Value != null ? row.Cells[19].Value : DBNull.Value);
            command.ExecuteNonQuery();

        }
    }

    maConnexion.Close();
    this.Hide();
    Repair rep = new Repair();
    rep.Show();
}
这是我的DB的图片:


我使用了调试器,但我的单元格似乎不正确。datagridview中的第一列是Machine,代码中对应的单元格是row.cells


似乎我所有的细胞都不像看上去那样排列整齐。这到底是什么?我的意思是,通常BoardName是第三个单元格,但我把行放在单元格[2]中,我不再有错误了。并不是只有一个单元格出现此错误。

使用您的更新更新:

您选择的单元格在数据库中具有相应的
int
值。我建议您检查您的
datagridview
population-至于要更改的行中的位置,代码中一定有更改

作为将来的参考,最好不要否认数据库表中存在int,因为它确实有助于回答问题,并且可以提供更简单的解决方案,并指导您查找

剩下的答案——虽然很有帮助——是现阶段的粉饰


使用

并且还使用

command.Parameters.Add(.../...
为了


在使用AddWithValue进行数据类型转换时,会遇到一些问题。

我总是使用这种类型的代码来处理SQL

 SqlConnection connection = new 
 SqlConnection(ConfigurationManager.AppSettings["SQLConnectionString"]);

 SqlCommand command = new SqlCommand();
 command.CommandTimeout = 1000;
 command.Connection = connection;
 command.CommandType = CommandType.StoredProcedure;
 command.CommandText = "KULLANICI_OKU";

 SqlParameter parameter = new SqlParameter();
 parameter.Direction = ParameterDirection.Input;
 parameter.ParameterName = "@KULLANICI";
 parameter.DbType = DbType.String;
 parameter.Value = user;
 command.Parameters.Add(parameter);

在我看来,使用存储过程是sql更好的方法

首先要知道的是:不能将
DBNull.Value
赋值到
字符串(
nvarchar
在SQL中)或其他结构值类型中,因为它们彼此不兼容。在
DBNull.Value
string
(或结构类型)之间使用三元运算符的常用方法是将
DBNull.Value
强制转换为
对象
类型

下面是一个如何对三元运算符中的
DBNull.Value
执行强制转换的示例:

// a & b are cell numbers for respective cells
// change to any number representing the cell order

foreach (DataGridViewRow row in dataGridView1.Rows)
{
    if ((row.Cells[20].Value != null) && (bool)row.Cells[20].Value)
    {
        SqlCommand command = maConnexion.CreateCommand();

        command = new SqlCommand("update FailAndPass set Machine=@machine, ProgCode=@pc, BoardName=@BName, BoardNumber=@BNumber, Tester=@T, DateTest=@DT, TimeTest=@TT, TimeStart=@TS, FComponent=@FC, Message=@Mess, TotalTestProg=@TTP, ReadValue=@RV, ValueReference=@VR, PTolerance=@PT, FaultCodeByOP=@FCBO, FaultDetail=@FD,  RepairingDate=@RD, RepairingTime = @RT, ReportingOperator=@RO WHERE SerialNum=@Serial", maConnexion);
        // other parameters

        // integer value parameter example
        command.Parameters.Add("@pc", SqlDbType.Int).Value = row.Cells[a].Value != null ? row.Cells[a]Value : (object)DBNull.Value;

        // string value parameter example
        command.Parameters.Add("@BName", SqlDbType.NVarChar).Value = (row.Cells[b].Value != null ? (object)row.Cells[b].Value : (object)DBNull.Value).ToString();

        // other parameters

        command.ExecuteNonQuery();

    }
}

// other stuff
如果编译器支持空合并运算符,则更简单:

// integer parameter
command.Parameters.Add("@pc", SqlDbType.Int).Value = row.Cells[a].Value ?? (object)DBNull.Value;

// string parameter
command.Parameters.Add("@BName", SqlDbType.NVarChar).Value = (row.Cells[b].Value ?? (object)DBNull.Value).ToString();
参考:


好的,我找到了问题的解决方案

代码如下:

private void metroButton1_Click(object sender, EventArgs e)
    {
        SqlConnection maConnexion = new SqlConnection("Server= localhost; Database= Seica_Takaya;Integrated Security = SSPI; ");
        maConnexion.Open();

        foreach (DataGridViewRow row in dataGridView1.Rows)
        {


            if ((row.Cells[20].Value != null) && (bool)row.Cells[20].Value)
            {

                SqlCommand command = maConnexion.CreateCommand();


                command = new SqlCommand("update FailAndPass set Machine=@machine, ProgCode=@pc, BoardName=@BName, BoardNumber=@BNumber, Tester=@T, DateTest=@DT, TimeTest=@TT, TimeStart=@TS, FComponent=@FC, Message=@Mess, TotalTestProg=@TTP, ReadValue=@RV, ValueReference=@VR, PTolerance=@PT, FaultDetail=@FD, RepairingDate=@RD, RepairingTime=@RT, ReportingOperator=@RO, FaultCodeByOP=@FCBO  WHERE SerialNum=@Serial", maConnexion);

                command.Parameters.AddWithValue("@Machine", row.Cells[1].Value != null ? row.Cells[1].Value : DBNull.Value);
                command.Parameters.AddWithValue("@Serial", textBox1.Text);
                command.Parameters.AddWithValue("@pc", row.Cells[3].Value != null ? row.Cells[3].Value : DBNull.Value);
                command.Parameters.AddWithValue("@BName", row.Cells[4].Value != null ? row.Cells[4].Value : DBNull.Value);
                command.Parameters.AddWithValue("@BNumber", row.Cells[5].Value != null ? row.Cells[5].Value : DBNull.Value);
                command.Parameters.AddWithValue("@T", row.Cells[6].Value != null ? row.Cells[6].Value : DBNull.Value);
                command.Parameters.AddWithValue("@DT", row.Cells[7].Value != null ? row.Cells[7].Value : DBNull.Value);
                command.Parameters.AddWithValue("@TT", row.Cells[8].Value != null ? row.Cells[8].Value : DBNull.Value);
                command.Parameters.AddWithValue("@TS", row.Cells[9].Value != null ? row.Cells[9].Value : DBNull.Value);
                command.Parameters.AddWithValue("@FC", row.Cells[11].Value != null ? row.Cells[11].Value : DBNull.Value);
                command.Parameters.AddWithValue("@Mess", row.Cells[10].Value != null ? row.Cells[10].Value : DBNull.Value);                   
                command.Parameters.AddWithValue("@TTP", row.Cells[12].Value != null ? row.Cells[12].Value : DBNull.Value);
                command.Parameters.AddWithValue("@RV", row.Cells[13].Value != null ? row.Cells[13].Value : DBNull.Value);
                command.Parameters.AddWithValue("@VR", row.Cells[14].Value != null ? row.Cells[14].Value : DBNull.Value);
                command.Parameters.AddWithValue("@PT", row.Cells[15].Value != null ? row.Cells[15].Value : DBNull.Value);
                command.Parameters.AddWithValue("@FD", row.Cells[16].Value != null ? row.Cells[16].Value : DBNull.Value);
                command.Parameters.AddWithValue("@RD", row.Cells[17].Value != null ? row.Cells[17].Value : DBNull.Value);
                command.Parameters.AddWithValue("@RT", row.Cells[18].Value != null ? row.Cells[18].Value : DBNull.Value);
                command.Parameters.AddWithValue("@RO", row.Cells[19].Value != null ? row.Cells[19].Value : DBNull.Value);
                command.Parameters.AddWithValue("@FCBO", row.Cells[20].Value != null ? row.Cells[20].Value : DBNull.Value);

                command.ExecuteNonQuery();




            }
        }
}

现在我可以用add替换所有addwithvalue

说明:单元格似乎不像列或索引那样被计数。我认为该单元格正在等待索引[0]->[max]。 或者,我看到该行。单元格[0]不包含计算机的名称,但为空。 结果是,如果我的单元格从索引[0]开始,我的所有数据都会偏移。然后,果然BoardName在ProgCode单元格中,因此插入到数据库中的ProgCode列中,该列为int类型,因此引发了错误


这真是令人兴奋,我已经一步一步地做到了。但是谢谢大家的帮助,因为至少你已经学到了一些东西

FailAndPass
中的所有列的类型都是
NVARCHAR
?我假设除了
SerialNum
之外的所有列都可以为空。尝试使用
DbType
为字符串参数指定数据类型,例如
command.parameters.AddWithValue(“@Machine”,row.Cells[0]。Value!=null?row.Cells[0]。Value:DBNull.Value)。DbType=DbType.string
.side注意:
private void AddParameter(SqlCommand命令,字符串参数名称,对象值){command.Parameters.AddWithValue(ParameterName,value!=null?value:DBNull.value);}
-引用博客文章“AddWithValue()有问题”函数:它必须为您的查询参数推断数据库类型。问题是:有时它会出错。“不是int!!!我已经对你的代码进行了测试,但仍然不能正常工作。我不认为它来自add。当我使用这种方式时,我有一个错误:System.FormatException:在int32中转换值字符串失败。“据我所知,单元格[0]是行选择器。哦,这解释了很多
// integer parameter
command.Parameters.Add("@pc", SqlDbType.Int).Value = row.Cells[a].Value ?? (object)DBNull.Value;

// string parameter
command.Parameters.Add("@BName", SqlDbType.NVarChar).Value = (row.Cells[b].Value ?? (object)DBNull.Value).ToString();
private void metroButton1_Click(object sender, EventArgs e)
    {
        SqlConnection maConnexion = new SqlConnection("Server= localhost; Database= Seica_Takaya;Integrated Security = SSPI; ");
        maConnexion.Open();

        foreach (DataGridViewRow row in dataGridView1.Rows)
        {


            if ((row.Cells[20].Value != null) && (bool)row.Cells[20].Value)
            {

                SqlCommand command = maConnexion.CreateCommand();


                command = new SqlCommand("update FailAndPass set Machine=@machine, ProgCode=@pc, BoardName=@BName, BoardNumber=@BNumber, Tester=@T, DateTest=@DT, TimeTest=@TT, TimeStart=@TS, FComponent=@FC, Message=@Mess, TotalTestProg=@TTP, ReadValue=@RV, ValueReference=@VR, PTolerance=@PT, FaultDetail=@FD, RepairingDate=@RD, RepairingTime=@RT, ReportingOperator=@RO, FaultCodeByOP=@FCBO  WHERE SerialNum=@Serial", maConnexion);

                command.Parameters.AddWithValue("@Machine", row.Cells[1].Value != null ? row.Cells[1].Value : DBNull.Value);
                command.Parameters.AddWithValue("@Serial", textBox1.Text);
                command.Parameters.AddWithValue("@pc", row.Cells[3].Value != null ? row.Cells[3].Value : DBNull.Value);
                command.Parameters.AddWithValue("@BName", row.Cells[4].Value != null ? row.Cells[4].Value : DBNull.Value);
                command.Parameters.AddWithValue("@BNumber", row.Cells[5].Value != null ? row.Cells[5].Value : DBNull.Value);
                command.Parameters.AddWithValue("@T", row.Cells[6].Value != null ? row.Cells[6].Value : DBNull.Value);
                command.Parameters.AddWithValue("@DT", row.Cells[7].Value != null ? row.Cells[7].Value : DBNull.Value);
                command.Parameters.AddWithValue("@TT", row.Cells[8].Value != null ? row.Cells[8].Value : DBNull.Value);
                command.Parameters.AddWithValue("@TS", row.Cells[9].Value != null ? row.Cells[9].Value : DBNull.Value);
                command.Parameters.AddWithValue("@FC", row.Cells[11].Value != null ? row.Cells[11].Value : DBNull.Value);
                command.Parameters.AddWithValue("@Mess", row.Cells[10].Value != null ? row.Cells[10].Value : DBNull.Value);                   
                command.Parameters.AddWithValue("@TTP", row.Cells[12].Value != null ? row.Cells[12].Value : DBNull.Value);
                command.Parameters.AddWithValue("@RV", row.Cells[13].Value != null ? row.Cells[13].Value : DBNull.Value);
                command.Parameters.AddWithValue("@VR", row.Cells[14].Value != null ? row.Cells[14].Value : DBNull.Value);
                command.Parameters.AddWithValue("@PT", row.Cells[15].Value != null ? row.Cells[15].Value : DBNull.Value);
                command.Parameters.AddWithValue("@FD", row.Cells[16].Value != null ? row.Cells[16].Value : DBNull.Value);
                command.Parameters.AddWithValue("@RD", row.Cells[17].Value != null ? row.Cells[17].Value : DBNull.Value);
                command.Parameters.AddWithValue("@RT", row.Cells[18].Value != null ? row.Cells[18].Value : DBNull.Value);
                command.Parameters.AddWithValue("@RO", row.Cells[19].Value != null ? row.Cells[19].Value : DBNull.Value);
                command.Parameters.AddWithValue("@FCBO", row.Cells[20].Value != null ? row.Cells[20].Value : DBNull.Value);

                command.ExecuteNonQuery();




            }
        }