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

DataGridView CellClick事件点击空值列报无法调用空值方法错误

报错根因
  • 触发空值异常的核心原因:RicercaEstrazioni字段配置为允许NULL,数据库返回的空值是DBNull.Value类型,和VB中的Nothing不是同一种类型,你写的两段代码都没有对该类型做校验,直接对空值对象调用GetString()、ToString()方法,就会抛出题目中的报错。
  • 两段代码还存在其他会引发异常或逻辑错误的问题:
    • 第一段数据库查询代码逻辑冗余:同一条SQL先后执行ExecuteNonQuery、SqlDataAdapter填充DataTable、SqlDataReader读取三套操作,属于重复查询浪费性能;同时字符串拼接SQL存在注入风险,数据库连接未做自动释放,容易触发连接泄漏;除第8列外,其他字段只要存储了NULL值,直接调用GetDateTime()、GetString()这类强类型读取方法一样会报错。
    • 第二段直接读取DataGridView行的代码存在列映射错误:txtEstratto3读取了Estratto2列的值,txtEstratto4读取了Estratto3列的值,txtEstratto5读取了Estratto4列的值,最后还把Estratto5列的值赋给了txtEstratto1,运行后文本框加载的内容会完全错位。
修复方案

优先选择直接读取DataGridView行的实现方案,无需每次点击都回库查询,响应速度更快、逻辑更简洁,修复后的完整代码如下:

Private Sub DataGridView1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
    ' 点击列头、行头等无效区域时直接退出
    If e.RowIndex < 0 Then Exit Sub
    Dim selectedRow As DataGridViewRow = DataGridView1.Rows(e.RowIndex)

    ' 封装通用空值安全读取方法,遇到DBNull/Nothing直接返回空字符串
    Dim SafeGetText = Function(cellValue As Object) As String
                          If cellValue Is DBNull.Value OrElse cellValue Is Nothing Then
                              Return String.Empty
                          End If
                          Return cellValue.ToString()
                      End Function

    ' 逐字段赋值,修正原代码的列映射错误
    txtId.Text = SafeGetText(selectedRow.Cells("id").Value)
    ' 日期选择控件单独处理空值,避免类型转换异常
    If TypeOf selectedRow.Cells("Data_Estraz").Value Is DateTime Then
        dtpDataEstrazione.Value = DirectCast(selectedRow.Cells("Data_Estraz").Value, DateTime)
    Else
        dtpDataEstrazione.Value = DateTime.Today
    End If
    txtRuota.Text = SafeGetText(selectedRow.Cells("Ruota").Value)
    txtEstratto1.Text = SafeGetText(selectedRow.Cells("Estratto1").Value)
    txtEstratto2.Text = SafeGetText(selectedRow.Cells("Estratto2").Value)
    txtEstratto3.Text = SafeGetText(selectedRow.Cells("Estratto3").Value)
    txtEstratto4.Text = SafeGetText(selectedRow.Cells("Estratto4").Value)
    txtEstratto5.Text = SafeGetText(selectedRow.Cells("Estratto5").Value)
    ' 核心修复:空值场景自动赋值空字符串,不会触发空值方法调用错误
    txtRicercaEstrazioni.Text = SafeGetText(selectedRow.Cells("RicercaEstrazioni").Value)
End Sub

如果你确实需要每次点击行都从数据库拉取最新数据(常规场景无必要,DataGridView绑定数据源时本身已经存储了全量行数据),需要注意两点:

  • 删掉冗余的查询执行逻辑,只保留DataReader读取流程即可,用Using块自动释放连接、命令、阅读器资源,改用参数化查询避免SQL注入
  • 所有字段读取前必须调用IsDBNull()做判断,不要直接调用强类型读取方法,比如第8列的读取逻辑要修改为:
' RicercaEstrazioni字段的安全读取写法
If dr.IsDBNull(8) Then
    txtRicercaEstrazioni.Text = String.Empty
Else
    txtRicercaEstrazioni.Text = dr.GetString(8)
End If

注意:只要是数据库中配置为允许NULL的字段,读取前必须做DBNull校验,这是ADO.NET数据读取的基础规则,跳过校验必然会在字段为空时抛出异常。

内容的提问来源于stack exchange,提问作者user19103492

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 02:27:18