我正在尝试创建一个删除按钮来删除记录....
这是我的代码:
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()非常烦人。
答案 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读取整数),几乎没有问题,但参数化查询总是更好