You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#操作Access数据库时遇Data type mismatch异常无法保存数据

解决Data Type Mismatch异常的方案

核心问题分析

  • OleDb参数按位置匹配而非名称匹配:你写的命名参数不会被OleDb识别,它只会按参数添加顺序对应SQL语句中VALUES的顺序。你的参数添加顺序和SQL字段顺序不匹配,还多了一个不必要的@id参数,直接导致类型不匹配。
  • 参数数量不匹配:SQL的VALUES里只有11个占位符,但你添加了12个参数(多了@id),引发匹配错误。
  • 未处理空值与类型转换:DataGridView单元格的值可能是DBNull.Value,或类型与数据库字段不匹配(比如数字字段传了未转换的object)。

修正步骤

1. 移除多余参数,匹配参数顺序

删除cmd.Parameters.AddWithValue("@id", ...)这一行(INSERT语句无对应字段),并确保参数添加顺序严格对应SQL中VALUES的字段顺序:
SQL字段顺序:CUST_ID, FIRST_NAME, LAST_NAME, ADDRESS, CITY, STATE, POSTAL, EMAIL, BALANCE, CREDIT_LIMIT, REP_ID

2. 显式转换数据类型,处理空值

针对数据库字段类型转换参数值,空值用DBNull.Value代替,避免类型不匹配。

修正后的代码

private void button2_Click_1(object sender, EventArgs e)
{
    string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:/Users/sdepasqu/Documents/Customer Database.accdb";

    // 连接放在循环外,减少资源消耗
    using (OleDbConnection conn = new OleDbConnection(connString))
    {
        conn.Open();
        // 用?作为占位符,更符合OleDb的位置匹配逻辑
        using (OleDbCommand cmd = new OleDbCommand(@"INSERT INTO customer([CUST_ID], [FIRST_NAME], [LAST_NAME], [ADDRESS], [CITY], [STATE], [POSTAL], [EMAIL], [BALANCE], [CREDIT_LIMIT], [REP_ID]) 
                                                    VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", conn))
        {
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                // 跳过DataGridView的空新行
                if (row.IsNewRow) continue;

                cmd.Parameters.Clear();

                // 按SQL字段顺序添加参数,显式处理类型和空值
                cmd.Parameters.AddWithValue("", row.Cells["cUSTIDDataGridViewTextBoxColumn"].Value ?? DBNull.Value);
                cmd.Parameters.AddWithValue("", row.Cells["fIRSTNAMEDataGridViewTextBoxColumn"].Value ?? DBNull.Value);
                cmd.Parameters.AddWithValue("", row.Cells["lASTNAMEDataGridViewTextBoxColumn"].Value ?? DBNull.Value);
                cmd.Parameters.AddWithValue("", row.Cells["aDDRESSDataGridViewTextBoxColumn"].Value ?? DBNull.Value);
                cmd.Parameters.AddWithValue("", row.Cells["cITYDataGridViewTextBoxColumn"].Value ?? DBNull.Value);
                cmd.Parameters.AddWithValue("", row.Cells["sTATEDataGridViewTextBoxColumn"].Value ?? DBNull.Value);
                cmd.Parameters.AddWithValue("", row.Cells["pOSTALDataGridViewTextBoxColumn"].Value ?? DBNull.Value);
                cmd.Parameters.AddWithValue("", row.Cells["eMAILDataGridViewTextBoxColumn"].Value ?? DBNull.Value);
                
                // BALANCE:转换为decimal类型
                var balanceVal = row.Cells["bALANCEDataGridViewTextBoxColumn"].Value;
                cmd.Parameters.AddWithValue("", balanceVal == DBNull.Value || balanceVal == null ? DBNull.Value : Convert.ToDecimal(balanceVal));
                
                // CREDIT_LIMIT:转换为decimal类型
                var creditLimitVal = row.Cells["cREDITLIMITDataGridViewTextBoxColumn"].Value;
                cmd.Parameters.AddWithValue("", creditLimitVal == DBNull.Value || creditLimitVal == null ? DBNull.Value : Convert.ToDecimal(creditLimitVal));
                
                // REP_ID:转换为int类型
                var repIdVal = row.Cells["rEPIDDataGridViewTextBoxColumn"].Value;
                cmd.Parameters.AddWithValue("", repIdVal == DBNull.Value || repIdVal == null ? DBNull.Value : Convert.ToInt32(repIdVal));

                cmd.ExecuteNonQuery();
            }
        }
    }
}

额外说明

  • 若你明确数据库字段的精确类型(比如CUST_ID是文本/数字),可以进一步精准转换(如文本用Convert.ToString()),确保完全匹配。
  • 把连接和命令放在循环外,避免重复创建销毁资源,提升执行效率。

内容的提问来源于stack exchange,提问作者Salvatore A Depasquale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 10:35:26