如何解决SQL中@userid2变量重复声明的错误?
解决SQL变量重复声明的问题
你遇到的错误变量名 '@userid2' 已声明,核心原因是你在循环中反复向同一个SqlCommand对象的参数集合添加同名参数。因为SqlCommand的Parameters集合是持久化的,第一次循环添加@userid2后,第二次循环再调用AddWithValue就会导致参数重复定义。
另外你的代码还有一个隐藏问题:循环中修改了CommandText但没有立即执行插入操作,而是等循环结束后才执行一次ExecuteNonQuery(),这样最终只会插入最后一条选中的行,而不是所有选中的行。
下面是修复后的完整代码,同时解决这两个问题:
Protected Sub btnmodifyaccessdepot_Click(sender As Object, e As EventArgs) Handles btnmodifyaccessdepot.Click Using con As New SqlConnection(ConString) con.Open() Dim sqlTran As SqlTransaction = con.BeginTransaction() Dim command As SqlCommand = con.CreateCommand() command.Transaction = sqlTran Try ' 1. 执行更新操作 command.CommandText = "UPDATE Rhema_TechnicalAccess set Active=@Active,Requester= @Requester,Approver=@Approver,Issuer=@Issuer where userid=@userid" command.Parameters.AddWithValue("@Active", lblactiveadd.Text) command.Parameters.AddWithValue("@Requester", lblrequesterAdd.Text) command.Parameters.AddWithValue("@Approver", lblapproveradd.Text) command.Parameters.AddWithValue("@Issuer", lblisssueradd.Text) command.Parameters.AddWithValue("@Userid", lblselecteduserid.Text) command.ExecuteNonQuery() ' 清空参数集合,准备插入操作 command.Parameters.Clear() ' 定义插入的SQL语句 command.CommandText = "INSERT INTO Rhema_TechnicalAccessDepot VALUES(@userid2,@Depot,@Access,@TechnicalAccessID)" ' 提前添加所有需要的参数(只添加一次) command.Parameters.Add("@userid2", SqlDbType.VarChar) ' 根据实际字段类型调整 command.Parameters.Add("@Depot", SqlDbType.VarChar) command.Parameters.Add("@Access", SqlDbType.VarChar) command.Parameters.Add("@technicalaccessid", SqlDbType.Int) ' 假设是整数类型,根据实际调整 ' 2. 循环处理选中的行,执行插入 For Each row As GridViewRow In gridadddepot.Rows If row.RowType = DataControlRowType.DataRow Then Dim chkdepots As CheckBox = DirectCast(row.FindControl("chkdepots"), CheckBox) If chkdepots.Checked Then Dim lbldepot As TextBox = DirectCast(row.FindControl("lbldepot"), TextBox) ' 只修改参数的值,而不是重复添加 command.Parameters("@userid2").Value = lblselecteduserid.Text command.Parameters("@Depot").Value = lbldepot.Text command.Parameters("@Access").Value = lbluseraccessAdd.Text command.Parameters("@technicalaccessid").Value = lbltechnicalaccessid.Text ' 立即执行插入 command.ExecuteNonQuery() End If End If Next sqlTran.Commit() lblmessage2.Text = "Both records were written to database." Catch ex As Exception lblmessage2.Text = ex.Message Try sqlTran.Rollback() Catch exRollback As Exception lblmessage2.Text = exRollback.Message End Try End Try End Using End Sub
关键修复点:
- 避免参数重复:执行完更新后,先清空参数集合,然后一次性添加插入所需的所有参数,在循环中只修改参数的值,而不是每次都调用
AddWithValue。 - 正确执行插入:在每次循环的选中行判断里,执行
ExecuteNonQuery(),确保每一行选中的数据都被插入。 - 优化参数定义:建议明确指定参数的
SqlDbType(比如SqlDbType.VarChar、SqlDbType.Int),而不是依赖AddWithValue自动推断,这样可以避免潜在的类型转换问题。
另外,还有一种替代方案是每次循环创建一个新的SqlCommand对象,但需要注意关联同一个事务:
' 在循环内创建新的Command Dim insertCmd As SqlCommand = con.CreateCommand() insertCmd.Transaction = sqlTran insertCmd.CommandText = "INSERT INTO Rhema_TechnicalAccessDepot VALUES(@userid2,@Depot,@Access,@TechnicalAccessID)" insertCmd.Parameters.AddWithValue("@userid2", lblselecteduserid.Text) ' ... 添加其他参数 insertCmd.ExecuteNonQuery()
这种方式也能避免参数重复,但相比之下,复用同一个Command并修改参数值的效率更高。
内容的提问来源于stack exchange,提问作者Oracle
相关产品推荐
相关产品推荐

