我正在尝试将Access数据库迁移到vb.net winform(.net框架)。我使用此软件的机会非常有限,因此我要部分解决每件事。我的目标是在任何人插手使用和访问数据库之前(一次一件事情)最终将数据转换为SQL Server。无论如何,我已经通过数据源建立了连接,创建了一个基本的登录表单,并重构了我从访问数据库中移植的代码。这就是我所拥有的...
Public intLogonAttempts As Long
Dim connection As New OleDbConnection(My.Settings.DataConnectionString)
Private Sub Btn_Login_Click(sender As Object, e As EventArgs) Handles Btn_Login.Click
Dim RetVal As Integer
' Check all information required has been inputted
If Txt_Username.Text = "" Then
MsgBox("Please enter a username.", vbOKOnly, "Required Data")
Txt_Username.Select()
Exit Sub
End If
If Txt_Password.Text = "" Then
MsgBox("Please enter a password.", vbOKOnly, "Required Data")
Txt_Password.Select()
Exit Sub
End If
'If connection.State = ConnectionState.Closed Then
' connection.Open()
'End If
Dim cmd As New OleDbCommand("SELECT * FROM User where [username] = ? AND [Password] = ?", connection)
cmd.Parameters.AddWithValue("@p1", Txt_Username.Text)
cmd.Parameters.AddWithValue("@p1", Txt_Password.Text)
connection.Open()
RetVal = CInt(cmd.ExecuteScalar())
If (RetVal = 1) Then
' Login successful
MsgBox("Successful login")
My.Settings.savedUsername = Txt_Username.Text
My.Settings.savedPassword = Txt_Password.Text
My.Settings.Save()
Else
' Login unsuccessful
intLogonAttempts = intLogonAttempts + 1
If intLogonAttempts >= 3 Then
MsgBox("You do not have access to this database. Please contact admin.", vbCritical, "Restricted Access!")
Application.Exit()
Exit Sub
Else
MsgBox("Password Invalid. Please Try Again", vbOKOnly, "Invalid Entry!")
Txt_Password.Select()
End If
End If
End Sub
但是,当我的代码达到“ RetVal = CInt(cmd.ExecuteScalar())”时,将返回以下错误;
System.Data.OleDb.OleDbException:“ FROM子句中的语法错误。”
我在这里出了什么问题?我以为这是由于sql语句引起的,但是我很确定自己有正确的答案吗?
答案 0 :(得分:1)
我已将代码分为不同的方法,以使每个方法仅执行一项工作。
GetUserCount
方法已与用户界面完全断开。用户可以从Web或电话应用程序登录,并且可以使用相同的方法。
对您的数据库对象使用Using...End Using
块。这样可以确保即使出现错误也可以将它们关闭并丢弃。我认为您从未断开连接。
请注意,Select
命令正在获取Count(*)
。在您的代码中,您得到的只是*,因此,使用.ExecuteScalar
,您将获得结果集第一行的第一列。不是您所需要的。
我使用参数名称只是为了提高可读性,因此,我们可以看到参数以与它们在Select语句中出现的顺序相同的顺序添加到参数集合中。
对参数使用.Add
方法。参见http://www.dbdelta.com/addwithvalue-is-evil/
和
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
还有一个:
https://dba.stackexchange.com/questions/195937/addwithvalue-performance-and-plan-cache-implications
这是另一个
https://andrevdm.blogspot.com/2010/12/parameterised-queriesdont-use.html
我不得不猜测数据类型和大小,因此,请检查数据库中的实际值。
您不应存储纯文本密码。那是您需要研究的单独主题。
Private intLogonAttempts As Integer 'You don't need a Long to hold 3
Private Sub Btn_Login_Click(sender As Object, e As EventArgs) Handles Btn_Login.Click
Dim RetVal As Integer
If ValidateInput() Then
RetVal = GetUserCount(Txt_Username.Text, Txt_Password.Text)
End If
If (RetVal = 1) Then
' Login successful
MsgBox("Successful login")
'Why are you storing this information?
My.Settings.savedUsername = Txt_Username.Text
My.Settings.savedPassword = Txt_Password.Text
My.Settings.Save()
Else
' Login unsuccessful
intLogonAttempts += 1
If intLogonAttempts >= 3 Then
MsgBox("You do not have access to this database. Please contact admin.", vbCritical, "Restricted Access!")
Application.Exit() 'Of course there is nothing to stop the user from restarting the app and trying 3 more times
Exit Sub
Else
'Don't tell the user what is wrong; that would help unauthorized users
'It could be the user name or the password
MsgBox("Please Try Again", vbOKOnly, "Invalid Entry!")
End If
End If
End Sub
Private Function ValidateInput() As Boolean
If Txt_Username.Text = "" Then
MsgBox("Please enter a username.", vbOKOnly, "Required Data")
Txt_Username.Select()
Return False
End If
If Txt_Password.Text = "" Then
MsgBox("Please enter a password.", vbOKOnly, "Required Data")
Txt_Password.Select()
Return False
End If
Return True
End Function
Private Function GetUserCount(UName As String, UPass As String) As Integer
'All the database code is here
Dim RetVal As Integer
Using connection As New OleDbConnection(My.Settings.DataConnectionString),
cmd As New OleDbCommand("SELECT Count(*) FROM [User] where [username] = @Name AND [Password] = @PWord;", connection)
cmd.Parameters.Add("@Name", OleDbType.VarChar, 100).Value = UName
cmd.Parameters.Add("@PWord", OleDbType.VarChar, 100).Value = UPass
connection.Open()
RetVal = CInt(cmd.ExecuteScalar())
End Using
Return RetVal
End Function
答案 1 :(得分:0)
我忘记了表名用户周围的[] ...
但是,为了不浪费这篇文章,人们是否能够建议这是否是执行登录的最佳方法,或者那里是否存在更好的解决方案?