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

如何解决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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:04:06