Pat*_*Pat 2 sql vb.net ado.net
我正在尝试构建我的第一个程序,并且我遇到了一些SQL问题.
我有一个客户和员工的数据库(除其他外),我正在尝试设置一个基本的登录屏幕.用户使用其EmployeeID(主键)登录
本部分首次涉及登录.
它会检查具有该ID的用户的数据库并获取密码.如果密码不为空/ null,则会显示一个消息框并停在那里.
如果密码为空/ null,则表示确认然后更新新密码.
这是我的理解结束的地方.调试显示错误肯定是在SQL更新中,但我看不到任何错误...
救命?
谢谢.
代码如下:
Private Sub NewPass()
Dim PassCheck As String
GetDatabase()
'Check if there is a password
SQLString = "SELECT EmployeeID, Password, Deleted FROM Employee "
SQLString += "WHERE EmployeeID= " & UserID
Try
connection.Open() ' Open Connection
If ConnectionState.Open.ToString = "Open" Then
command = New System.Data.OleDb.OleDbCommand(SQLString, connection)
datareader = command.ExecuteReader()
If datareader.HasRows Then
If datareader.Item("Deleted") = False Then
'Password check
outputString = datareader.Item("Password").ToString
Else
outputString = ""
End If
End If 'recordset has rows
datareader.Close()
End If
Catch ex As Exception 'Display Error message
MessageBox.Show("Error accessing database", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
connection.Close()
PassCheck = outputString
If String.IsNullOrEmpty(PassCheck) = True Then
GetDatabase()
SQLString = "UPDATE Employee SET "
SQLString += "Password = '" & Password & "' "
SQLString += "WHERE EmployeeID = " & UserID
'Try
connection.Open()
If ConnectionState.Open.ToString = "Open" Then
'Update Password
command = New System.Data.OleDb.OleDbCommand(SQLString, connection)
command.ExecuteNonQuery()
MainMenuForm.Show()
Me.Hide()
Else
outputString = ""
MessageBox.Show("Error opening connection")
End If
connection.Close()
'Catch ex As Exception
'End Try
Else
MessageBox.Show("This Account has a password", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
FirstTimeButton.Show()
FirstTimeBool = False
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
GetDatabase()
Private Sub GetDatabase()
'Locates the Database
Try
ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data "
ConnectionString += "Source=" & System.Windows.Forms.Application.StartupPath & "\PharmacyDatabase.accdb "
connection = New System.Data.OleDb.OleDbConnection(ConnectionString)
Catch ex As Exception 'No Database Found
MessageBox.Show("No Database Found in \Debug", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Run Code Online (Sandbox Code Playgroud)
我不想成为坏消息的承载者,但那里存在很多错误,包括多个严重的安全问题和潜在的拒绝服务漏洞.请尝试下面的代码.您需要这里提供的BCrypt库:http://derekslager.com/blog/posts/2007/10/bcrypt-dotnet-strong-password-hashing-for-dotnet-and-mono.ashx
首先,一个新的GetDatabase()函数:
Private Function GetDatabase() As OleDbConnection
Return New System.Data.OleDbOleDbConnection(string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}\PharmacyDatabase.accdb", System.Windows.Forms.Application.StartupPath))
End Function
Run Code Online (Sandbox Code Playgroud)
这是违反直觉的,但是由于连接池,在.Net中每次创建新连接确实更好.
然后,主要功能:
Private Sub NewPass()
Dim sql As String = "UPDATE Employee SET Password = ? WHERE EmployeeID= ? AND Password IS NULL"
Dim resultCount As Integer
Using cn As System.Data.OleDb.OleDbCommand = GetDatabase(), _
command As New System.Data.OleDb.OleDbCommand(sql, cn)
command.Parameters.Add("Password", OleDbType.Char, 60).Value = BCrypt.HashPassword(password, BCrypt.GenerateSalt(12))
command.Parameters.Add("UserID", OleDbType.Integer).Value = UserId
cn.Open()
resultCount = command.ExecuteNonQuery()
End Using
If resultCount <> 1 Then
'If a password was already set (password field not null), resultCount will be zero
MessageBox.Show("This Account does not exist or already has a password", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
FirstTimeButton.Show()
FirstTimeBool = False
Else
MainMenuForm.Show()
Me.Hide()
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
该代码中有一些东西完全缺失,所以我想解释它们的去向.首先是没有connection.Close().这完全由Using块处理,并且处理得更好,因为Using块确保即使抛出异常也会关闭连接.
接下来是Try/Catch块.我的感觉是这是检查错误的错误代码级别.关于异常的奇妙之处在于它们爬上了堆栈.通常最好将您的try/catch保存为更接近UI的代码,因为它通常更适合知道如何响应.因此,直接与数据库对话的代码应该让异常发生,业务或表示层可以决定如何处理它.
最后缺失的部分是连接状态检查.实际上,只有在尝试从错误中恢复时,或者在您希望保持打开状态的长期连接的情况下,才需要在异常处理程序中进行连接状态检查.正如我已经说过的,我不相信这个级别的代码是错误处理的正确位置,而.Net在短期连接方面做得更好,所以我们可以完全跳过这个.