使用SqlParameter和For循环插入DataGridView数据报错求助
问题场景
我尝试通过SqlParameter结合for循环将DataGridView中的数据插入数据库,编写代码如下:
Dim sqlAddCmd As New SqlCommand sqlAddCmd.CommandText = "INSERT INTO TableName (Val,Idx,Ref,Sta,Col,Point,Mat,Refer,Cover,IDNo,Mas)" _ & "VALUES (@Val,@No,@Ref,@Sta,@Col,@Point,@Mat,@Refer,@Cover,@IDNo,@Mast)" sqlAddCmd.Transaction = transaction With sqlAddCmd.Parameters .Add("@Val", SqlDbType.Int) .Add("@No", SqlDbType.TinyInt) .Add("@Ref", SqlDbType.Char) .Add("@Sta", SqlDbType.Char) .Add("@Col", SqlDbType.VarChar) .Add("@Point", SqlDbType.SmallInt) .Add("@Mat", SqlDbType.VarChar) .Add("@Refer", SqlDbType.Int) .Add("@Cover", SqlDbType.TinyInt) .Add("@IDNo", SqlDbType.VarChar) .Add("@Mast", SqlDbType.Char) End With For intI = 0 To daGridView.Rows.Count With sqlAddCmd .Parameters("@Val").Value = lngNewID .Parameters("@No").Value = daGridView.Rows(intI).Cells("dgvNo").Value .Parameters("@Ref").Value = daGridView.Rows(intI).Cells("dgvRef").Value .Parameters("@Sta").Value = daGridView.Rows(intI).Cells("dgvSta").Value .Parameters("@Col").Value = daGridView.Rows(intI).Cells("dgvCol").Value .Parameters("@Point").Value = daGridView.Rows(intI).Cells("dgvPoint").Value .Parameters("@Mat").Value = daGridView.Rows(intI).Cells("dgiMat").Value .Parameters("@Refer").Value = daGridView.Rows(intI).Cells("dgiRefer").Value .Parameters("@Cover").Value = daGridView.Rows(intI).Cells("dgiCover").Value .Parameters("@IDNo").Value = daGridView.Rows(intI).Cells("dgiIDNo").Value .Parameters("@Mast").Value = daGridView.Rows(intI).Cells("dgiMast").Value End With sqlAddCmd.ExecuteNonQuery() Next
执行时出现报错:
The Variable Name @Val has already been declared. Variable must be unique within a query batch or stored procedure.
Must declare the scalar variable @No.
问题原因与解决方法
循环边界错误
原代码循环条件For intI = 0 To daGridView.Rows.Count会导致索引越界:DataGridView的行索引范围是0到Rows.Count - 1,最后一行通常是未编辑的空新行(默认允许添加行时)。越界访问会引发异常,同时可能导致参数赋值失败,触发@No未声明的错误。
修正为:For intI = 0 To daGridView.Rows.Count - 1 ' 跳过空的新行 If daGridView.Rows(intI).IsNewRow Then Continue For ' 赋值与执行代码 Next参数重复添加风险
如果这段代码被多次执行(比如放在重复触发的事件中),sqlAddCmd.Parameters.Add会重复添加同名参数,导致@Val已声明的错误。可以在初始化参数前清空集合:sqlAddCmd.Parameters.Clear() ' 添加这句 With sqlAddCmd.Parameters .Add("@Val", SqlDbType.Int) ' ...其他参数添加 End With单元格名称匹配问题
检查代码中单元格名称(如dgiMat、dgiRefer)是否与DataGridView的列名完全一致,拼写错误会导致无法获取值,间接引发参数未绑定的报错。确保所有单元格名称与界面列的Name属性一致。额外优化建议
若数据量较大,推荐使用SqlBulkCopy进行批量插入,效率远高于循环执行ExecuteNonQuery;数据量较小时,当前方法调整后即可正常运行。
内容的提问来源于stack exchange,提问作者Mr Bim

