出于某种原因,当我尝试将数据添加到我的数据库时,我一直得到:
System.Data.dll中出现'System.Data.OleDb.OleDbException'类型的第一次机会异常
其他信息:SQL语句末尾缺少分号(;)。
这是我的代码。现在我已经安装了数据库引擎,并且已经将cpu更改为x86。
Private Sub SaveButton_Click(sender As Object, e As EventArgs) Handles SaveButton.Click
If DirectCast(AdminCheckBox, CheckBox).Checked = True Then
Dim result1 As Integer
Dim cmd As New OleDb.OleDbCommand
cnn = New OleDb.OleDbConnection
cnn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & "C:\Users\daNo\Documents\Visual Studio 2013\Projects\WindowsApplication1\WindowsApplication1\bin\chem.accdb;"
If Not cnn.State = ConnectionState.Open Then
cnn.Open()
End If
result1 = MsgBox("Are you sure you want to add this user a admin?", MsgBoxStyle.YesNo, "Add New User")
If result1 = vbYes Then
cmd.Connection = cnn
cmd.CommandText = "INSERT INTO Users(UserName, [password], Email) " & _
"VALUES(?,?,?)'"
cmd.Parameters.AddWithValue("@p1", Me.UserNameTextBox.Text)
cmd.Parameters.AddWithValue("@p2", Me.PasswordTextBox2.Text)
cmd.Parameters.AddWithValue("@p3", Me.EmailTextBox.Text)
cmd.ExecuteNonQuery()
MsgBox("Account has been created!", MsgBoxStyle.OkOnly, "Add New User")
Dim ACCSETTINGS As New ACCSETTINGS
ACCSETTINGS.Show()
Me.Hide()
Me.Close()
ElseIf result1 = vbNo Then
Dim NEWUSER As New NewUser
NEWUSER.Show()
Me.Hide()
End If
End If
答案 0 :(得分:1)
用户名,密码和电子邮件是文本字段,因此您需要传递用单引号括起来的值。您的命令错过了构建命令的字符串连接中的值周围的这些引号。像这样的东西
"INSERT INTO Users(UserName, [password], Email) VALUES('" & Me.UserNameTextBox.Text & "'....
但这是构建sql命令的一种非常糟糕的方法。您应该始终使用参数化查询
Dim result1 = MsgBox("Are you sure you want to add this user a admin?", MsgBoxStyle.YesNo, "Add New User")
If result1 = vbYes Then
Using cnn = New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;.....")
Using cmd = new OleDb.OleDbCommand("INSERT INTO Users(UserName, [password], Email) " & _
"VALUES(?,?,?)"
cnn.Open()
cmd.Parameters.AddWithValue("@p1",Me.UserNameTextBox.Text)
cmd.Parameters.AddWithValue("@p2",Me.PasswordTextBox2.Text)
cmd.Parameters.AddWithValue("@p3",Me.EmailTextBox.Text)
Dim rowAdded = cmd.ExecuteNonQuery()
if rowAdded > 0 Then
MessageBox.Show("Account has been created!")
....
Else
MessageBox.Show("Problems!")
End If
End If
参数化查询不需要通过连接用户的输入值,添加字符串所需的引号(最终解析嵌入式引号),在需要时检查正确的小数分隔符,以正确的格式传递日期来构造复杂的查询文本但最重要的是,参数化查询消除了Sql Injection恶意用户准备可能对数据库造成严重破坏的特殊格式化字符串的可能性。
作为旁注。从安全角度来看,以明文形式存储密码确实是一种不好的做法。根据您的应用程序的上下文,这是一个不要淡化的事情。如果有人可以获取您的数据库文件的副本,他可以读取存储的每个用户密码。
编辑
再次检查连接字符串中使用的字符串以设置数据库名称,显示它确实是错误的。
此处,为便于阅读而拆分
"...;Data Source=" & Application.StartupPath & "C:\Users\daNo\Documents\" & _
"Visual Studio 2013\Projects\WindowsApplication1\WindowsApplication1\bin\chem.accdb;..."
这会导致数据库的路径错误。如果您有一个固定的位置来存储accdb文件,那么您可以删除Application.StartupPath