无法将值插入MS Access数据库

时间:2017-05-19 07:22:14

标签: vb.net ms-access

任何人都可以查看下面的代码,并告知这有什么问题吗?

我试图将值插入MS Access数据库。编译器不会抛出任何错误,但值不会插入表中。

代码:

Private Sub btnSignInOK_Click(sender As Object, e As EventArgs) Handles btnSignInOK.Click

    uniqid = "1"

    Try
        Dim ConnSignIn As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Resources\DBpPNRGENERATORDATA.accdb;Persist Security Info=True")
        Dim CmdSignIn As New OleDb.OleDbCommand

        If Not ConnSignIn.State = ConnectionState.Open Then
            ConnSignIn.Open()
        End If

        CmdSignIn.Connection = ConnSignIn
        CmdSignIn.CommandText = "DELETE TEMPSIGNIN.* FROM TEMPSIGNIN WHERE IDENTIFIER='" + uniqid + "'"
        CmdSignIn.ExecuteNonQuery()


        CmdSignIn.CommandText = "INSERT INTO TEMPSIGNIN(IDENTIFIER,EPR,Partition,Host)VALUES('" & uniqid & "','" & tbSigninEPR.Text & "','" & cbSignInPartition.Text & "','" & tbSignInAl.Text & "')"
        CmdSignIn.ExecuteNonQuery()

    Catch ex As Exception

        MessageBox.Show(ex.Message)

    End Try

3 个答案:

答案 0 :(得分:1)

DELETE命令不太正确。您不需要在命令中指定列,因为您要删除行而不是列:

DELETE FROM [TableName]

接下来,您应该在执行SQL命令时使用参数。这是为了减少语法问题,但更重要的是停止SQL注入。有关详细信息,请参阅Bobby Tables。我在使用参数时在SQL命令中使用?占位符。我还指定了数据类型,因此请考虑使用OleDbParameter Constructor (String, OleDbType)添加参数。

我还会考虑实施Using

  

托管资源由.NET Framework垃圾收集器(GC)处理,无需您进行任何额外编码。对于托管资源,您不需要使用“使用”块。但是,您仍然可以使用“使用”块来强制处理受管资源,而不是等待垃圾回收器。

您可以检查ExecuteNonQuery()返回的值,以查看在插入新行之前是否删除了该行。

所有代码看起来都像这样:

uniqid = "1"
Dim rowDeleted As Boolean

Using con As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Resources\DBpPNRGENERATORDATA.accdb;Persist Security Info=True")
    Using cmd As New OleDbCommand("DELETE FROM [TEMPSIGNIN] WHERE [IDENTIFIER] = ?", con)
        con.Open()

        cmd.Parameters.Add("@Id", OleDbType.Integer).Value = uniqid

        rowDeleted = cmd.ExecuteNonQuery() = 1
    End Using

    If rowDeleted Then
        Using cmd As New OleDbCommand("INSERT INTO [TEMPSIGNIN] ([IDENTIFIER], [EPR], [Partition], [Host]) VALUES (?, ?, ?, ?)", con)

            cmd.Parameters.Add("@Id", OleDbType.[Type]).Value = uniqid
            cmd.Parameters.Add("@EPR", OleDbType.[Type]).Value = tbSigninEPR.Text
            cmd.Parameters.Add("@Partition", OleDbType.[Type]).Value = cbSignInPartition.Text
            cmd.Parameters.Add("@Host", OleDbType.[Type]).Value = tbSignInAl.Text

            cmd.ExecuteNonQuery()
        End Using
    End If
End Using
  

请注意,我使用了OleDbType.[Type]。您需要将[Type]替换为您在数据库中使用的数据类型。

答案 1 :(得分:0)

如上所述,DELETE SQL的语法错误。因此,当数据库尝试执行它时,它会失败,因此INSERT永远不会运行。将DELETE更改为:

 CmdSignIn.CommandText = "DELETE FROM TEMPSIGNIN WHERE IDENTIFIER='" + uniqid + "'"

此外,您应该学习如何使用SQL参数,而不是使用字符串连接来创建SQL字符串。使用参数你的DELETE查询变得类似(这不是100%,它不在我的头顶)

CmdSignIn.CommandText = "DELETE FROM TEMPSIGNIN WHERE IDENTIFIER=@ID"
CmdSignIn.Parameters.Add("@ID", uniqid)
CmdSignIn.ExecuteNonQuery()

答案 2 :(得分:0)

好的,关注为什么没有抛出任何异常,无论使用何种语法。您确定要定位正确的物理数据库吗?

如果目标是正确的数据库,如果数据库在解决方案资源管理器中然后选择数据库,选择属性,检查属性“复制到输出目录”,默认为“始终复制”,如果您有此设置,则在每个构建数据库时在项目文件夹中覆盖app文件夹目录中的数据库,因此不会有任何更改。

旁注: 根据目前提供的建议,这是一个需要考虑的模式。将所有数据库操作放在它自己的类中。下面的类是简单的,读取,更新,添加和删除MS-Access数据库表客户(对于此示例)主键,公司名称和联系人姓名。

它自己的函数中的每个操作都有错误处理,如果失败,你可以返回异常(我只是使用此示例的异常消息)。

使用BindingSource,因为此组件在遍历数据绑定控件(如TextBoxes和/或DataGridView)时可以更轻松。

表单代码在DataGridView中显示数据,有一个用于删除当前记录的按钮和一个用于添加新记录的按钮(我省略了断言以查看TextBoxes是否有数据)。我使用两个TextBox控件来获取插入记录的信息。

表格代码

Public Class StackOverFlowForm1
    Private Operations As New Sample2
    Private bsCustomers As New BindingSource
    Private Sub StackOverFlowForm1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim ops As New Sample2
        If ops.LoadCustomers Then
            bsCustomers.DataSource = ops.CustomersDataTable
            DataGridView1.DataSource = bsCustomers
        Else
            MessageBox.Show($"Failed to load table data{Environment.NewLine}{ops.Exception.Message}")
        End If
    End Sub
    Private Sub cmdDeleteCurrent_Click(sender As Object, e As EventArgs) Handles cmdDeleteCurrent.Click
        If bsCustomers.Current IsNot Nothing Then
            Dim ops As New Sample2
            Dim currentIdentifier As Integer = CType(bsCustomers.Current, DataRowView).Row.Field(Of Integer)("Identifier")
            If Not ops.DeleteCustomer(currentIdentifier) Then
                MessageBox.Show($"Failed to remove customer: {ops.Exception.Message}")
            Else
                bsCustomers.RemoveCurrent()
            End If
        End If
    End Sub
    Private Sub cmdInsert_Click(sender As Object, e As EventArgs) Handles cmdInsert.Click
        Dim ops As New Sample2
        Dim newId As Integer = 0
        If ops.AddNewRow(txtCompanyName.Text, txtContact.Text, newId) Then
            CType(bsCustomers.DataSource, DataTable).Rows.Add(New Object() {newId, txtCompanyName.Text, txtContact.Text})
        Else
            MessageBox.Show($"Failed to add customer: {ops.Exception.Message}")
        End If
    End Sub
End Class

然后我们有一个数据库操作类。该数据库位于app文件夹中。

Public Class Sample2
    Private Builder As New OleDbConnectionStringBuilder With
    {
        .Provider = "Microsoft.ACE.OLEDB.12.0",
        .DataSource = IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Database1.accdb")
    }

    Private mExceptiom As Exception
    ''' <summary>
    ''' Each method when executed, if there is an exception thrown
    ''' then mException is set and can be read back via Exception property
    ''' only when a method returns false.
    ''' </summary>
    ''' <returns></returns>
    Public ReadOnly Property Exception As Exception
        Get
            Return mExceptiom
        End Get
    End Property
    ''' <summary>
    ''' Container for data read in from a database table
    ''' </summary>
    ''' <returns></returns>
    Public Property CustomersDataTable As DataTable
    Public Function LoadCustomers() As Boolean
        If Not IO.File.Exists(Builder.DataSource) Then
            Return False
        End If

        Try

            CustomersDataTable = New DataTable

            Using cn As New OleDbConnection With {.ConnectionString = Builder.ConnectionString}
                Using cmd As New OleDbCommand With {.Connection = cn}
                    cmd.CommandText = "SELECT Identifier, CompanyName, ContactTitle FROM Customers"

                    cn.Open()

                    CustomersDataTable.Load(cmd.ExecuteReader)
                    CustomersDataTable.DefaultView.Sort = "CompanyName"
                    CustomersDataTable.Columns("Identifier").ColumnMapping = MappingType.Hidden

                End Using
            End Using

            Return True
        Catch ex As Exception
            mExceptiom = ex
            Return False
        End Try
    End Function
    ''' <summary>
    ''' Delete a customer by their primary key
    ''' </summary>
    ''' <param name="CustomerId"></param>
    ''' <returns></returns>
    Public Function DeleteCustomer(ByVal CustomerId As Integer) As Boolean
        Dim Success As Boolean = True
        Dim Affected As Integer = 0

        Try
            Using cn As New OleDbConnection With {.ConnectionString = Builder.ConnectionString}
                Using cmd As New OleDbCommand With {.Connection = cn}
                    cmd.CommandText = "DELETE FROM Customers WHERE Identifier = @Identifier"

                    cmd.Parameters.AddWithValue("@Identifier", CustomerId)

                    cn.Open()

                    Affected = cmd.ExecuteNonQuery()
                    If Affected = 1 Then
                        Success = True
                    End If
                End Using
            End Using
        Catch ex As Exception
            Success = False
            mExceptiom = ex
        End Try

        Return Success

    End Function
    Public Function UpdateCustomer(ByVal CustomerId As Integer, ByVal CompanyName As String, ByVal ContactName As String) As Boolean
        Dim Success As Boolean = True
        Dim Affected As Integer = 0

        Try
            Using cn As New OleDbConnection With {.ConnectionString = Builder.ConnectionString}
                Using cmd As New OleDbCommand With {.Connection = cn}
                    cmd.CommandText = "UPDATE Customer SET CompanyName = @CompanyName, ContactName = @ContactName WHERE Identifier = @Identifier"

                    cmd.Parameters.AddWithValue("@CompanyName", CompanyName)
                    cmd.Parameters.AddWithValue("@ContactName", ContactName)
                    cmd.Parameters.AddWithValue("@Identifier", ContactName)

                    cn.Open()

                    Affected = cmd.ExecuteNonQuery()
                    If Affected = 1 Then
                        Success = True
                    End If
                End Using
            End Using
        Catch ex As Exception
            Success = False
            mExceptiom = ex
        End Try

        Return Success

    End Function
    ''' <summary>
    ''' Add new row, if successful provide the new record's primary key
    ''' </summary>
    ''' <param name="Name"></param>
    ''' <param name="ContactName"></param>
    ''' <param name="Identfier"></param>
    ''' <returns></returns>
    Public Function AddNewRow(ByVal Name As String, ByVal ContactName As String, ByRef Identfier As Integer) As Boolean
        Dim Success As Boolean = True

        Try
            Using cn As New OleDbConnection With {.ConnectionString = Builder.ConnectionString}
                Using cmd As New OleDbCommand With {.Connection = cn}
                    cmd.CommandText = "INSERT INTO Customers (CompanyName,ContactName) Values(@CompanyName,@ContactName)"

                    cmd.Parameters.AddWithValue("@CompanyName", Name)
                    cmd.Parameters.AddWithValue("@ContactName", ContactName)

                    cn.Open()
                    Dim Affected As Integer = cmd.ExecuteNonQuery()
                    If Affected = 1 Then
                        cmd.CommandText = "Select @@Identity"
                        Identfier = CInt(cmd.ExecuteScalar)
                    End If
                End Using
            End Using
        Catch ex As Exception
            Success = False
            mExceptiom = ex
        End Try

        Return Success

    End Function
End Class