从表中删除错误

时间:2014-08-24 16:41:46

标签: sql vb.net

我正在尝试创建一个删除按钮来删除记录....

这是我的代码:

    Dim SqlQuery As String = "DELETE FROM MyTable WHERE InvoiceNumber = " & id & ";"
    'id is public shared as integer , which is ListView1.SelectedItems(0).Text
    Dim SqlCommand As New OleDb.OleDbCommand

    With SqlCommand
        .CommandText = SqlQuery
        .Connection = conn
        .ExecuteNonQuery()
    End With

我在.ExecuteNonQuery()中遇到异常,错误是

 "ExecuteNonQuery() requires the command to have a transaction" ,
 "Validate transaction" , "ExecuteReaderInternal"

假设数据库已连接,获取信息和删除按钮为button3。

此外,我将向您展示我的整个表格代码:

Public Class Report
Public id As Integer

Public conn As New OleDb.OleDbConnection
Public connstring As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Ramy\Documents\Beach.accdb"


Private Property RivieraDataSet As Object

Private Sub Report_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    conn.Close()
End Sub

Private Sub Report_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    If conn.State = ConnectionState.Closed Then
        Try
            conn.ConnectionString = connstring
            conn.Open()
            MsgBox("DataBase opened successfully!", MsgBoxStyle.Exclamation)
            loadlistview()
        Catch ex As Exception
            MsgBox(ex.ToString, MsgBoxStyle.Critical)
        End Try
    Else
        MsgBox("DataBase Error!!", MsgBoxStyle.Critical)
    End If
    Dim reading As OleDb.OleDbDataReader
    Dim cmd As New OleDb.OleDbCommand
    Dim trans As OleDb.OleDbTransaction
    trans = conn.BeginTransaction
    cmd.CommandText = "SELECT * FROM MyTable"
    cmd.Connection = conn
    cmd.Transaction = trans
    reading = cmd.ExecuteReader
    Dim i
    Do While reading.Read
        i = Val(reading.Item("Total")) + i
    Loop
    TextBox7.Text = i
    TextBox7.Text = Convert.ToDecimal(TextBox7.Text).ToString("N2") & " L.E"

End Sub

Sub loadlistview()
    ListView1.FullRowSelect = True
    ListView1.MultiSelect = False
    ListView1.View = View.Details

    ListView1.Columns.Clear()
    ListView1.Items.Clear()


    ListView1.Columns.Add("No", 30, HorizontalAlignment.Left)
    ListView1.Columns.Add("InvoiceDate", 125, HorizontalAlignment.Left)
    ListView1.Columns.Add("PersonsNumber", 70, HorizontalAlignment.Left)
    ListView1.Columns.Add("PersonPrice", 80, HorizontalAlignment.Left)
    ListView1.Columns.Add("CashierName", 100, HorizontalAlignment.Left)
    ListView1.Columns.Add("Total", 100, HorizontalAlignment.Left)



    Dim SqlQuery As String = "SELECT * FROM MyTable"
    Dim SqlCommand As New OleDb.OleDbCommand
    Dim SqlAdapter As New OleDb.OleDbDataAdapter
    Dim table As New DataTable

    With SqlCommand
        .CommandText = SqlQuery
        .Connection = conn
    End With

    With SqlAdapter
        .SelectCommand = SqlCommand
        .Fill(table)
    End With

    For i = 0 To table.Rows.Count - 1
        With ListView1
            .Items.Add(table.Rows(i)("InvoiceNumber"))
            With .Items(.Items.Count - 1).SubItems
                .Add(table.Rows(i)("InvoiceDate"))
                .Add(table.Rows(i)("PersonsNumber"))
                .Add(table.Rows(i)("PersonPrice"))
                .Add(table.Rows(i)("CashierName"))
                .Add(table.Rows(i)("Total"))
            End With
        End With
    Next
End Sub

Private Sub ListView1_MouseClick(sender As Object, e As MouseEventArgs) Handles ListView1.MouseClick

    Dim SqlQuery As String = "SELECT * FROM MyTable"
    Dim SqlCommand As New OleDb.OleDbCommand
    Dim SqlAdapter As New OleDb.OleDbDataAdapter
    Dim table As New DataTable

    With SqlCommand
        .CommandText = SqlQuery
        .Connection = conn
    End With

    With SqlAdapter
        .SelectCommand = SqlCommand

    End With



    If ListView1.SelectedItems.Count > 0 Then
        id = ListView1.SelectedItems(0).Text
        TextBox1.Text = id
        TextBox6.Text = ListView1.SelectedItems(0).SubItems(1).Text
        TextBox3.Text = ListView1.SelectedItems(0).SubItems(2).Text
        TextBox4.Text = ListView1.SelectedItems(0).SubItems(3).Text
        TextBox2.Text = ListView1.SelectedItems(0).SubItems(4).Text
        TextBox5.Text = ListView1.SelectedItems(0).SubItems(5).Text
    End If
End Sub



Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    Dim SqlQuery As String = "DELETE FROM MyTable WHERE InvoiceNumber = " & id & ";"
    'id is public shared as integer , which is ListView1.SelectedItems(0).Text
    Dim SqlCommand As New OleDb.OleDbCommand

    With SqlCommand
        .CommandText = SqlQuery
        .Connection = conn
        .ExecuteNonQuery()
    End With

End Sub
End Class

我在删除btn代码中搜索了几个小时的错误,但我可以看到一切都很好.....但.ExecuteNonQuery()非常烦人。

1 个答案:

答案 0 :(得分:0)

Form_Load中,您为GLOBAL连接打开了一笔交易 这意味着应该将使用该连接执行的每个命令通知此事务(并且您在Form_Load事件中设置Command.Transaction属性)。 但是在程序的其他部分中,使用该连接执行命令而不设置Transaction属性将引发上述错误。

查看上面的代码,我建议完全删除交易,因为您不需要它。

只需在Form_Load中删除这些行

即可
Dim trans As OleDb.OleDbTransaction
trans = conn.BeginTransaction
...
cmd.Transaction = trans

相反,如果出于上述代码中不明显的动机,您坚持保留事务,那么您应该从连接创建命令,以便将事务传递给命令。

Dim SqlQuery As String = "DELETE FROM MyTable WHERE InvoiceNumber = " & id & ";"
Dim SqlCommand = conn.CreateCommand()
With SqlCommand
  .... 
End With

顺便说一下,我真的建议你删除那个全局连接变量。它只是问题的根源(检查是否打开,事务等...)只需创建一个为您创建它的函数,并在需要时在Using语句中使用它

Public Function GetConnection() As OleDb.OleDbConnection
   Dim conn = New OleDb.OleDbConnection(connstring)
   conn.Open()
   return conn
End Function

并将其与Using Statement一起使用,以便在出现异常情况时关闭并处理所包含的对象

Using conn = GetConnection()
Using command = conn.CreateCommand()
    With command
       command.CommandText = "DELETE FROM MyTable WHERE InvoiceNumber = " & id & ";"
       command.ExecuteNonQuery()
    End With
End Using
End Using

请注意可能的sql注入方案。在您的情况下(从ListView读取整数),几乎没有问题,但参数化查询总是更好