VB.NET DataGridView插入SQL数据报@KodeBuku未提供错误
问题根因
这个报错核心触发原因是遍历DataGridView行时没有过滤控件自动生成的末尾空白新行:
默认配置下DataGridView的AllowUserToAddRows属性为开启状态,控件最底部会保留一行供用户录入新数据的空白行,这行的 IsNewRow 属性为True,所有单元格的Value都是VB中的Nothing空引用。AddWithValue方法接收到Nothing作为参数值时,不会自动转换为数据库可识别的DBNull,而是直接判定该参数未完成赋值,最终抛出你看到的"@KodeBuku未提供"异常。你观察到部分数据能成功写入,是因为前面的有效数据行执行插入时参数值正常,遍历到最后一行空白新行时才触发报错。
原代码还存在几个潜在问题:
- 每次循环都新建、释放数据库连接,批量插入时性能很差
- 没有做统一空值处理,就算跳过空白新行,有效行内如果有单元格未填内容,一样会触发同类参数错误
- INSERT语句未显式指定列名,后续表结构变动时极易出现字段匹配错误
修复方案
调整代码逻辑,新增新行过滤、空值转换逻辑,同时优化连接复用,修改后代码如下:
' 数据库连接移到循环外创建,复用连接降低开销 Dim constring As String = "data source=MSI;initial catalog=DB_PERPUS;integrated security=true" Using conn As New SqlConnection(constring) conn.Open() For Each row As DataGridViewRow In dgv_buku.Rows ' 跳过DataGridView自动生成的末尾空白新行 If row.IsNewRow Then Continue For Using cmd As New SqlCommand("INSERT INTO Tbl_Buku (KodeBuku,JudulBuku,PengarangBuku,PenerbitBuku,TahunBuku,StokBuku) VALUES (@KodeBuku,@JudulBuku,@PengarangBuku,@PenerbitBuku,@TahunBuku,@StokBuku)", conn) ' 空值显式转换为DBNull,避免被判定为参数未赋值 cmd.Parameters.AddWithValue("@KodeBuku", If(row.Cells("kode").Value, DBNull.Value)) cmd.Parameters.AddWithValue("@JudulBuku", If(row.Cells("judul").Value, DBNull.Value)) cmd.Parameters.AddWithValue("@PengarangBuku", If(row.Cells("pengarang").Value, DBNull.Value)) cmd.Parameters.AddWithValue("@PenerbitBuku", If(row.Cells("penerbit").Value, DBNull.Value)) cmd.Parameters.AddWithValue("@TahunBuku", If(row.Cells("tahun").Value, DBNull.Value)) cmd.Parameters.AddWithValue("@StokBuku", If(row.Cells("stok").Value, DBNull.Value)) cmd.ExecuteNonQuery() End Using Next conn.Close() End Using MsgBox("保存成功")
额外排查点
如果修改后仍触发同类报错,按以下顺序检查:
- 核对DataGridView列的
Name属性,确认和row.Cells("xxx")中传入的字符串完全匹配,拼写、大小写错误都会导致取值为Nothing - 如果数据库中对应字段设置了非空约束,要在插入前增加必填项校验,提示用户补全内容,不要直接传入
DBNull - 追求更高性能的场景下,可以显式指定每个SqlParameter的数据库类型、长度,替代
AddWithValue的自动类型推导,避免参数被默认定义为nvarchar(4000)带来的隐式转换开销
内容的提问来源于stack exchange,提问作者Jenny
相关产品推荐
相关产品推荐

