Mysql 未处理无效的操作异常-can';不要一次更新两件事

Mysql 未处理无效的操作异常-can';不要一次更新两件事,mysql,vb.net,xampp,Mysql,Vb.net,Xampp,我制作的这个表单允许用户更改他们的用户名、密码和/或安全密码短语,它连接并更新XAMPP数据库。我试过上网,但我对VB很陌生,没有什么真正有意义的 问题是我可以更改其中任何一个,但如果在更改一个后尝试更改另一个,则会出现错误: 未处理InvalidOperationException 连接必须有效且打开 错误出现在这里:reader=objcommand.ExecuteReader 这是我的代码: `导入MySql.Data 导入MySql.Data.MySqlClient 公共类frmAcco

我制作的这个表单允许用户更改他们的用户名、密码和/或安全密码短语,它连接并更新XAMPP数据库。我试过上网,但我对VB很陌生,没有什么真正有意义的

问题是我可以更改其中任何一个,但如果在更改一个后尝试更改另一个,则会出现错误: 未处理InvalidOperationException 连接必须有效且打开

错误出现在这里:reader=objcommand.ExecuteReader

这是我的代码:

`导入MySql.Data 导入MySql.Data.MySqlClient

公共类frmAccountSettings

Private Sub frmAccountSettings_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    objconnection.Open()
    objdataadapter.SelectCommand = New MySqlCommand
    objdataadapter.SelectCommand.Connection = objconnection
    objdataadapter.SelectCommand.CommandText = "Select * FROM Login"
End Sub

Private Sub btnBack_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBack.Click
    frmMainMenu.Show()
    Me.Hide()
End Sub

Private Sub btnChangeUsername_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnChangeUsername.Click
    Dim password1, newusername As String
    password1 = InputBox("What is the current password?")
    sqlstring = "SELECT password FROM Login WHERE Password = '" &
password1 & "'"
    objcommand = New MySqlCommand(sqlstring, objconnection)
    reader = objcommand.ExecuteReader

    If reader.Read Then
        reader.Close()
        newusername = InputBox("Enter a new username")
        sqlstring = "UPDATE `Login` SET `username` =  '" & newusername &
"'  WHERE `Login`.`password` = '" & password1 & "'"
        objdataadapter.SelectCommand.CommandText = sqlstring
        objdataadapter.SelectCommand.CommandType = CommandType.Text

        objdataset = New DataSet
        objdataadapter.Fill(objdataset, "Login")

        objconnection.Close()

    Else
        MsgBox("Incorrect Username. Please make sure your credentials are correct and try again.", MsgBoxStyle.Critical, "Authentication Failed")
        reader.Close()
    End If
End Sub

Private Sub btnChangePassword_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnChangePassword.Click
    Dim oldpassword, newpassword1 As String
    oldpassword = InputBox("What is the current password?")
    sqlstring = "SELECT password FROM Login WHERE Password = '" &
oldpassword & "'"
    objcommand = New MySqlCommand(sqlstring, objconnection)
    reader = objcommand.ExecuteReader

    If reader.Read Then
        reader.Close()
        newpassword1 = InputBox("Enter a new password")
        sqlstring = "UPDATE `Login` SET `password` =  '" & newpassword1 &
"'  WHERE `Login`.`password` = '" & oldpassword & "'"
        objdataadapter.SelectCommand.CommandText = sqlstring
        objdataadapter.SelectCommand.CommandType = CommandType.Text

        objdataset = New DataSet
        objdataadapter.Fill(objdataset, "Login")

        objconnection.Close()

    Else
        MsgBox("Incorrect Password. Please make sure your credentials are correct and try again.", MsgBoxStyle.Critical, "Authentication Failed")
        reader.Close()
    End If
End Sub

Private Sub btnChangeSecurity_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnChangeSecurity.Click
    Dim password2, newsecurity As String
    password2 = InputBox("What is the current password?")
    sqlstring = "SELECT password FROM Login WHERE Password = '" &
password2 & "'"
    objcommand = New MySqlCommand(sqlstring, objconnection)
    reader = objcommand.ExecuteReader

    If reader.Read Then
        reader.Close()
        newsecurity = InputBox("Enter a new security passphrase")
        sqlstring = "UPDATE `Login` SET `security` =  '" & newsecurity &
"'  WHERE `Login`.`password` = '" & password2 & "'"
        objdataadapter.SelectCommand.CommandText = sqlstring
        objdataadapter.SelectCommand.CommandType = CommandType.Text

        objdataset = New DataSet
        objdataadapter.Fill(objdataset, "Login")

        objconnection.Close()

    Else
        MsgBox("Incorrect Password. Please make sure your credentials are correct and try again.", MsgBoxStyle.Critical, "Authentication Failed")
        reader.Close()
    End If
End Sub
末级
`我认为您的代码中有几个错误。最严重的是逻辑缺陷。
您无法确保两个用户选择的密码总是不同的。您需要确保datatable的
登录
用户名
字段上有一个
主键
,并在查询中使用该字段来唯一标识要更改的记录。此外,更改用作主键的用户名也不是一件容易的事情。您需要检查新用户名是否已被其他用户使用。如果您的应用程序在共享环境中使用,您还需要考虑并发更改(两个用户决定将其用户名更改为相同的新名称)

此外,适配器的
SelectCommand
不是执行数据库更新的适当方法。但是,这些操作根本不需要涉及适配器,您可以使用
MySqlCommand
完成所有操作

在数据表中以明文形式存储密码还有另一个安全问题。您不应该这样做,而是应该在将密码存储到表中之前对其应用哈希函数

但是,将我的答案限制在当前问题上,并排除并发问题,我将以这种方式更改您的代码(当然,
用户名
应该是主键)

通过这种方式,您可以使用用户和密码的组合来唯一地标识数据库中的用户,并更改所涉及的确切记录

同样,当您想要更改密码字段并仅在用户名和密码匹配时更新该字段时,您会要求输入用户名和密码

编辑根据您的上述评论,如果数据库中只有一个用户,则您可以直接执行更改,而无需进行任何复杂的检查。(但这确实是一个不能被认为是普遍存在的情况)

另一个问题是连接对象。它是在Form_Load事件中打开的全局对象,然后一直挂在代码周围,但在某些地方,您关闭了它,并且在尝试执行另一个数据库操作时,忘记了在中重新打开它。最好不要为连接使用全局对象,而是在需要时构建一个,使用它然后销毁它

比如说

Private Sub btnChangeSecurity_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnChangeSecurity.Click
    Using objconnection = new MySqlConnection(....connectionstring goes here ....)
        objconnection.Open()
        Dim sqlstring = "UPDATE `Login` SET `username` =  @newame WHERE `password` = @pwd"
        objcommand = New MySqlCommand(sqlstring, objconnection)
        objcommand.Parameters.AddWithValue("@newame", newusername)
        objcommand.Parameters.AddWithValue("@pwd", password1)
        objcommand.ExecuteNonQuery()
    End Using
End Sub

如果您将数据库访问代码放入上面的using语句中,您将创建连接对象,打开它,使用它,完成后,End using语句将关闭并销毁连接。

如果多个用户具有相同的密码,会发生什么情况?我的系统中只会有一个用户。这会影响代码吗?当然,这是一个改变游戏规则的情况。但是,不要使用适配器来执行这种更改,直接使用mysqlcommands抱歉我不知道,但是我对VB/MySQL非常陌生,只使用老师给出的注释。你能告诉我我需要在我的代码中更改什么吗?我已经用一个命令直接更新了下面的答案来更改用户名。从那里,您可以将相同的技术应用于代码中的其他事件。感谢您的帮助,非常感谢!
    sqlstring = "UPDATE `Login` SET `username` =  @newame WHERE `password` = @pwd"
    objcommand = New MySqlCommand(sqlstring, objconnection)
    objcommand.Parameters.AddWithValue("@newame", newusername)
    objcommand.Parameters.AddWithValue("@pwd", password1)
    objcommand.ExecuteNonQuery()
Private Sub btnChangeSecurity_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnChangeSecurity.Click
    Using objconnection = new MySqlConnection(....connectionstring goes here ....)
        objconnection.Open()
        Dim sqlstring = "UPDATE `Login` SET `username` =  @newame WHERE `password` = @pwd"
        objcommand = New MySqlCommand(sqlstring, objconnection)
        objcommand.Parameters.AddWithValue("@newame", newusername)
        objcommand.Parameters.AddWithValue("@pwd", password1)
        objcommand.ExecuteNonQuery()
    End Using
End Sub