如何将DataGridView数据保存到已连接Visual Studio的Access数据库
问题诊断
你的代码存在以下几类核心错误:
- SQL语法拼写错误:插入语句关键字
INSERT被误写为inserto,直接导致SQL执行失败。 - 参数化查询逻辑完全错误:你定义了带参数占位符的SQL模板,但后续没有给任何参数赋值,反而直接拼接单元格值到SQL字符串末尾,拼接后的SQL语法完全不合法,且参数数量与插入列数量不匹配:你插入的表有11个字段,但原SQL的VALUES后仅写了10个参数,缺少
CodigoProduto字段对应的参数。 - 未过滤DataGridView的空白新行:DataGridView默认会在最后显示一条待输入的空白新行,直接遍历所有行插入会触发空值报错。
- 资源管理不规范:没有自动释放数据库连接、命令对象资源,异常场景下可能出现连接泄漏。
- 字段与参数对应关系混乱:OleDb的参数是按位置匹配而非按名称匹配,参数赋值顺序必须和INSERT语句后的字段顺序完全一致,原代码完全没有遵循这个规则。
修正后的实现代码
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click Try ' Using语句会自动释放连接、命令资源,无需手动关闭 Using cn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source= |DataDirectory|\GEFORSERVI V2.1.accdb;") cn.Open() ' 修正SQL拼写,补充缺失的CodigoProduto字段参数,保证参数数量和字段数量一致 Dim Strcommandtext As String = "INSERT INTO Factura(Designacao,PrecoUnitario,Qtd,Total,Nome,Entidade,NIF,Telefone,Morada,CodigoProduto,DataEmissao) VALUES(@Designacao,@PrecoUnitario,@Qtd,@Total,@Nome,@Entidade,@NIF,@Telefone,@Morada,@CodigoProduto,@DataEmissao)" Using cmd As New OleDbCommand(Strcommandtext, cn) cmd.CommandType = CommandType.Text ' 提前定义参数,后续循环只改值就行,不用重复创建 cmd.Parameters.Add("@Designacao", OleDbType.VarChar) cmd.Parameters.Add("@PrecoUnitario", OleDbType.Decimal) cmd.Parameters.Add("@Qtd", OleDbType.Integer) cmd.Parameters.Add("@Total", OleDbType.Decimal) cmd.Parameters.Add("@Nome", OleDbType.VarChar) cmd.Parameters.Add("@Entidade", OleDbType.VarChar) cmd.Parameters.Add("@NIF", OleDbType.VarChar) cmd.Parameters.Add("@Telefone", OleDbType.VarChar) cmd.Parameters.Add("@Morada", OleDbType.VarChar) cmd.Parameters.Add("@CodigoProduto", OleDbType.VarChar) cmd.Parameters.Add("@DataEmissao", OleDbType.Date) ' 遍历行,跳过空白新行 For i As Integer = 0 To Factura2DataGridView.Rows.Count - 1 Dim row = Factura2DataGridView.Rows(i) If row.IsNewRow Then Continue For ' 跳过空白待输入行 ' 按顺序给参数赋值,注意Cells的索引要和你DataGridView里的列顺序对应,可根据实际列的位置调整索引值 cmd.Parameters("@Designacao").Value = If(row.Cells(0).Value Is DBNull.Value, "", row.Cells(0).Value) cmd.Parameters("@PrecoUnitario").Value = If(row.Cells(1).Value Is DBNull.Value, 0, row.Cells(1).Value) cmd.Parameters("@Qtd").Value = If(row.Cells(2).Value Is DBNull.Value, 0, row.Cells(2).Value) cmd.Parameters("@Total").Value = If(row.Cells(3).Value Is DBNull.Value, 0, row.Cells(3).Value) cmd.Parameters("@Nome").Value = If(row.Cells(4).Value Is DBNull.Value, "", row.Cells(4).Value) cmd.Parameters("@Entidade").Value = If(row.Cells(5).Value Is DBNull.Value, "", row.Cells(5).Value) cmd.Parameters("@NIF").Value = If(row.Cells(6).Value Is DBNull.Value, "", row.Cells(6).Value) cmd.Parameters("@Telefone").Value = If(row.Cells(7).Value Is DBNull.Value, "", row.Cells(7).Value) cmd.Parameters("@Morada").Value = If(row.Cells(8).Value Is DBNull.Value, "", row.Cells(8).Value) cmd.Parameters("@CodigoProduto").Value = If(row.Cells(9).Value Is DBNull.Value, "", row.Cells(9).Value) cmd.Parameters("@DataEmissao").Value = If(row.Cells(10).Value Is DBNull.Value, Date.Now, row.Cells(10).Value) cmd.ExecuteNonQuery() Next End Using End Using MsgBox("记录插入成功") Catch myException As Exception MsgBox("记录插入失败:" & myException.ToString()) End Try End Sub
内容的提问来源于stack exchange,提问作者Rosario Dilo
相关产品推荐
相关产品推荐

