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

VB.NET实现DataGridView批量更新MySQL表并求和的方法

批量更新MySQL库存实现方案

你现有代码存在几个会直接导致功能异常/安全风险的问题:

  • 逻辑漏洞:定义了IncomingStok变量但从未将DataGridView中取到的Stok值赋值给它,计算时永远加0,更新结果完全不符合预期
  • 执行冲突:DataReader会独占数据库连接,在Reader未关闭的状态下用同一个连接执行Update命令,会直接触发连接占用异常
  • 性能问题:每遍历一行就新建、打开、关闭一次数据库连接,数据量稍大时执行效率极低,还会耗尽连接池资源
  • 安全风险:直接拼接SQL字符串,存在SQL注入漏洞,恶意输入可直接篡改、删除全表数据
  • 资源泄漏:连接、命令、数据读取器对象都未做释放处理,长期运行会导致数据库连接泄漏

核心实现逻辑

不需要先查询原有库存值再在本地计算求和,MySQL原生支持UPDATE语句内直接做字段累加,单条SQL就能完成「取原有值+求和+更新」全流程,完全省去SELECT查询的开销:

UPDATE tbStok SET Stok = Stok + @新增库存值 WHERE ID = @对应ID

配合单次打开连接、参数化传值、事务包裹一致性保证,即可高效安全完成批量更新。


修正后的可运行代码

' 第一步:提前校验所有行数据合法性,避免执行到一半报错中断
Dim validRows As New List(Of (Id As Integer, IncomingStok As Integer))()
For Each row As DataGridViewRow In dgvStok.Rows
    If row.IsNewRow Then Continue For
    ' 做空值、格式校验,防止非法值导致执行报错
    Dim idVal As Integer
    Dim stokVal As Integer
    If Not Integer.TryParse(row.Cells("ID").Value?.ToString(), idVal) Then
        Throw New Exception($"第{row.Index + 1}行ID格式非法")
    End If
    If Not Integer.TryParse(row.Cells("Stok").Value?.ToString(), stokVal) Then
        Throw New Exception($"第{row.Index + 1}行库存值格式非法")
    End If
    validRows.Add((idVal, stokVal))
Next

' 替换为你自己的数据库连接字符串
Using conn As New MySqlConnection("你的数据库连接字符串")
    conn.Open()
    ' 开启事务,保证所有更新要么全成功要么全回滚,避免部分更新导致数据不一致
    Using tran As MySqlTransaction = conn.BeginTransaction()
        Try
            ' 复用同一个命令对象,只定义一次参数结构,减少重复创建开销
            Dim cmd As New MySqlCommand("UPDATE tbStok SET Stok = Stok + @incomingStok WHERE ID = @id", conn, tran)
            cmd.Parameters.Add("@incomingStok", MySqlDbType.Int32)
            cmd.Parameters.Add("@id", MySqlDbType.Int32)

            For Each item In validRows
                cmd.Parameters("@id").Value = item.Id
                cmd.Parameters("@incomingStok").Value = item.IncomingStok
                Dim affectRows = cmd.ExecuteNonQuery()
                ' 校验更新结果,ID不存在时直接终止回滚
                If affectRows = 0 Then
                    Throw New Exception($"ID为{item.Id}的库存记录不存在,更新终止")
                End If
            Next

            ' 所有行执行完成提交事务
            tran.Commit()
            MessageBox.Show("批量库存更新完成")
        Catch ex As Exception
            ' 出错时回滚所有已执行的变更
            tran.Rollback()
            Throw New Exception($"更新失败:{ex.Message}")
        End Try
    End Using
End Using

大数据量优化建议

如果单次更新的数据量超过1000条,可改用临时表+批量导入+关联更新的方案,性能比逐行执行UPDATE高10~100倍:

  1. 创建和tbStok结构匹配的临时表,仅保留ID、待新增库存两个字段
  2. 用MySqlBulkCopy把DataGridView中校验通过的待更新数据批量导入临时表
  3. 执行单条关联更新SQL完成全量更新:
    UPDATE tbStok t INNER JOIN 临时表 tmp ON t.ID = tmp.ID SET t.Stok = t.Stok + tmp.Stok
    
  4. 执行完成后临时表会自动回收,无需额外处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:33:25