使用TextBox插入数据库数据时遇NullReferenceException错误的解决方法
问题分析与解决
错误根源
DataGridView空值未处理
循环中直接调用dataGridView1.Rows[i].Cells[0].Value.ToString(),若单元格值为null,执行ToString()会直接触发NullReferenceException;另外未跳过DataGridView默认的空新行,也会导致无效判断。SQL插入操作用法错误
SqlDataAdapter.Fill()仅用于执行SELECT语句填充DataTable,不能用来执行INSERT这类非查询操作,这会导致插入逻辑无效,同时可能引发潜在的空引用问题。未管理数据库连接状态
若connect对象未正确初始化或未打开连接,会直接导致数据库操作失败。存在SQL注入风险
直接拼接TextBox内容到SQL语句中,不仅容易被注入攻击,若输入包含单引号还会直接报错。
修正后的完整代码
// 检查重复ID,处理空值与新行 bool isDuplicate = false; for (int i = 0; i < dataGridView1.Rows.Count; i++) { // 跳过DataGridView自动生成的空新行 if (dataGridView1.Rows[i].IsNewRow) continue; var cellValue = dataGridView1.Rows[i].Cells[0].Value; // 先判断值不为null,再做字符串比较 if (cellValue != null && textBox1.Text == cellValue.ToString()) { MessageBox.Show("This ID is already exist", "Something went wrong", MessageBoxButtons.OK, MessageBoxIcon.Warning); textBox1.Focus(); isDuplicate = true; break; } } if (isDuplicate) return; // 执行数据库插入操作 string query = "INSERT INTO InOrder(InodID, OrderNum, SuppID, CarID, Price, Amount, OrderDate) VALUES (@InodID, @OrderNum, @SuppID, @CarID, @Price, @Amount, @OrderDate)"; using (SqlCommand cmd = new SqlCommand(query, connect)) { // 使用参数化查询,避免SQL注入并保证类型匹配 cmd.Parameters.AddWithValue("@InodID", textBox1.Text); cmd.Parameters.AddWithValue("@OrderNum", textBox2.Text); cmd.Parameters.AddWithValue("@SuppID", textBox3.Text); cmd.Parameters.AddWithValue("@CarID", textBox4.Text); // 注意:如果Price/Amount是数值类型,需转换为对应CLR类型(示例用decimal/int) cmd.Parameters.AddWithValue("@Price", decimal.Parse(textBox5.Text)); cmd.Parameters.AddWithValue("@Amount", int.Parse(textBox6.Text)); // 日期直接传DateTime类型,不要用文本 cmd.Parameters.AddWithValue("@OrderDate", dateTimePicker1.Value); try { // 确保数据库连接处于打开状态 if (connect.State != ConnectionState.Open) { connect.Open(); } int rowsAffected = cmd.ExecuteNonQuery(); if (rowsAffected > 0) { MessageBox.Show("Your data successfully saved", "Congratulation", MessageBoxButtons.OK, MessageBoxIcon.None); // 插入成功后刷新DataGridView显示最新数据 RefreshDataGridView(); } else { MessageBox.Show("Failed to save data", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } catch (Exception ex) { MessageBox.Show($"Error: {ex.Message}", "Database Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { // 确保连接关闭,避免资源泄漏 if (connect.State == ConnectionState.Open) { connect.Close(); } } } // 刷新DataGridView的辅助方法 private void RefreshDataGridView() { DataTable dt = new DataTable(); string selectQuery = "SELECT * FROM InOrder"; using (SqlDataAdapter sda = new SqlDataAdapter(selectQuery, connect)) { sda.Fill(dt); dataGridView1.DataSource = dt; } }
核心修正说明
- 空值与新行处理:跳过DataGridView的空新行,先判断单元格值不为null再执行字符串转换,彻底避免空引用错误。
- 正确执行插入操作:用
SqlCommand.ExecuteNonQuery()执行插入,这是处理非查询SQL语句的标准方式,还能通过受影响行数判断操作是否成功。 - 参数化查询:彻底杜绝SQL注入风险,同时解决输入含单引号的报错问题,保证数据类型与数据库字段匹配。
- 连接状态管理:通过try-finally确保数据库连接正确关闭,避免资源泄漏。
- 刷新表格:插入成功后重新查询数据库,更新DataGridView显示最新数据。
内容的提问来源于stack exchange,提问作者Bakhtiyar_Dler
相关产品推荐
相关产品推荐

