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