我有一些代码将数据插入到访问数据库中的2个表中。看看我的代码,我认为可能有更好的方法来编写这个并成为VB.NET的新用户,会很感激一些帮助。我正在使用的代码工作正常,但它是正确的。
我知道此代码的sql注入问题,并将更改为生产的参数。
评论会很棒,因为我还在学习。非常感谢
For i = 0 To lvSelectedItems.Items.Count - 1
box = lvSelectedItems.Items.Item(i).Text
custref = lvSelectedItems.Items.Item(i).SubItems.Item(1).Text
sql = "Insert into Requests ([Request no], Customer, Dept, [Type], [Service level], " &
"[Date-time received], [Received by], [Date-time due], Quantity, [Cust requestor], Status) " &
"Values ('" & itm & "', '" & cmbCustomer.Text & "', '" & cmbDept.Text & "', 'B', '" & rbServiceLevel.ToString & "', " &
"'" & dtpDateReceived.Value & "', '" & txtBy.Text & "', '" & dtpDateDue.Value & "', '" & txtBoxQuantity.Text & "', '" & cmbRequestBy.Text & "', 'O')"
oledbCmd.CommandText = sql
oledbCmd.Connection = oledbCnn
dr = oledbCmd.ExecuteReader()
dr.Close()
sql = "Insert into [Request Boxes] ([Request no], Customer, Box) " &
"Values ('" & itm2 & "', '" & cmbCustomer.Text & "', '" & box.ToString & "')"
oledbCmd.CommandText = sql
oledbCmd.Connection = oledbCnn
dr = oledbCmd.ExecuteReader()
Next
MessageBox.Show("You have successfully completed the activity", "Box return successfull")
Close()
代码更新
Try
' Here the connection should be already open
' VB.NET will insist on inserting the parenthesis in the code below.
' which is different to your code example.
OleDbTransaction(tran = oledbCnn.BeginTransaction())
oledbCmd.Transaction = tran
For i = 0 To lvSelectedItems.Items.Count - 1
box = lvSelectedItems.Items.Item(i).Text
custref = lvSelectedItems.Items.Item(i).SubItems.Item(1).Text
sql = "Insert into Requests ([Request no], Customer, Dept, [Type], [Service level], " &
"[Date-time received], [Received by], [Date-time due], Quantity, [Cust requestor], " &
"Status) Values (?, ?, ?, 'B', ?, ?, ?, ?, ?, ?, '0')"
oledbCmd.Parameters.Clear()
oledbCmd.CommandText = sql
oledbCmd.Connection = oledbCnn
oledbCmd.Parameters.AddWithValue("@p1", itm)
oledbCmd.Parameters.AddWithValue("@p2", cmbCustomer.Text)
oledbCmd.Parameters.AddWithValue("@p3", cmbDept.Text)
oledbCmd.Parameters.AddWithValue("@p4", rbServiceLevel.ToString)
oledbCmd.Parameters.AddWithValue("@p5", dtpDateReceived.Value)
oledbCmd.Parameters.AddWithValue("@p6", txtBy.Text)
oledbCmd.Parameters.AddWithValue("@p7", dtpDateDue.Value)
oledbCmd.Parameters.AddWithValue("@p8", txtBoxQuantity.Text)
oledbCmd.Parameters.AddWithValue("@p9", cmbRequestBy.Text)
Dim rowsAffected = oledbCmd.ExecuteNonQuery()
If rowsAffected = 0 Then
' Fail to insert. Display a message and rollback everything
tran.Rollback()
Return
End If
sql = "Insert into [Request Boxes] ([Request no], Customer, Box) " &
"Values (?,?,?)"
oledbCmd.CommandText = sql
oledbCmd.Parameters.Clear()
oledbCmd.Parameters.AddWithValue("@p1", itm2)
oledbCmd.Parameters.AddWithValue("@p2", cmbCustomer.Text)
oledbCmd.Parameters.AddWithValue("@p3", box.ToString)
rowsAffected = oledbCmd.ExecuteNonQuery()
If rowsAffected = 0 Then
' Fail to insert. Display a Message and rollback everything
tran.Rollback()
Return
End If
Next
' if we reach this point, then all the commands have been
' completed correctly we could commit everything
tran.Commit()
Catch ex As Exception
Console.WriteLine(ex.Message)
tran.Rollback()
End Try
答案 0 :(得分:2)
您的代码似乎不正确,但包含非常糟糕的做法和ExecuteReader
的不当使用。
首先,不要使用字符串连接来构建sql命令。这使得门打开sql injection security并解析由于用户输入中存在的单引号等字符引起的问题。应使用parameterized query来避免此问题。
二。 ExecuteReader
用于阅读,不应用于插入数据。虽然ExecuteReader
也适用于INSERT查询,但最好使用ExecuteNonQuery
来了解您的插入是否成功
' Here the connection should be already open
Dim tran as OleDbTransaction = oledbCnn.BeginTransaction()
Try
oledbCmd.Transaction = tran
For i = 0 To lvSelectedItems.Items.Count - 1
box = lvSelectedItems.Items.Item(i).Text
custref = lvSelectedItems.Items.Item(i).SubItems.Item(1).Text
sql = "Insert into Requests ([Request no], Customer, Dept, [Type], [Service level], " &
"[Date-time received], [Received by], [Date-time due], Quantity, [Cust requestor], " &
"Status) Values (?, ?, ?, 'B', ?, ?, ?, ?, ?, ?, '0')"
oledbCmd.Parameters.Clear()
oledbCmd.CommandText = sql
oledbCmd.Connection = oledbCnn
oledbCmd.Parameters.AddWithValue("@p1", itm)
oledbCmd.Parameters.AddWithValue("@p2", cmbCustomer.Text )
oledbCmd.Parameters.AddWithValue("@p3", cmbDept.Text)
oledbCmd.Parameters.AddWithValue("@p4", rbServiceLevel.ToString)
oledbCmd.Parameters.AddWithValue("@p5", dtpDateReceived.Value)
oledbCmd.Parameters.AddWithValue("@p6", txtBy.Text)
oledbCmd.Parameters.AddWithValue("@p7", dtpDateDue.Value)
oledbCmd.Parameters.AddWithValue("@p8", txtBoxQuantity.Text)
oledbCmd.Parameters.AddWithValue("@p9", cmbRequestBy.Text )
Dim rowsAffected = oledbCmd.ExecuteNonQuery()
if rowsAffected = 0 Then
' Fail to insert. Display a message and rollback everything
tran.Rollback()
return
End If
sql = "Insert into [Request Boxes] ([Request no], Customer, Box) " &
"Values (?,?,?)"
oledbCmd.CommandText = sql
oledbCmd.Parameters.Clear()
oledbCmd.Parameters.AddWithValue("@p1", itm2)
oledbCmd.Parameters.AddWithValue("@p2", cmbCustomer.Text )
oledbCmd.Parameters.AddWithValue("@p3", box.ToString)
rowsAffected = oledbCmd.ExecuteNonQuery()
if rowsAffected = 0 Then
' Fail to insert. Display a Message and rollback everything
tran.Rollback()
return
End If
Next
' if we reach this point, then all the commands have been
' completed correctly we could commit everything
tran.Commit()
Catch ex As Exception
Console.WriteLine(ex.Message)
tran.Rollback()
End Try
答案 1 :(得分:2)
除了您已经说过的字符串连接问题,我建议您进行以下更改:
1。使用oledbCmd.ExecuteNonQuery()
代替oledbCmd.ExecuteReader()
。
oledbCmd.CommandText = sql
oledbCmd.Connection = oledbCnn
oledbCmd.ExecuteNonQuery()
2。利用事务来维护数据库的一致性,即成功执行所有插入或不执行任何插入。
oleDbTran = oledbCnn.BeginTransaction()
Try
For i = 0 To lvSelectedItems.Items.Count - 1
' loop with inserts
Next
oleDbTran.Commit()
Catch
oleDbTran.Rollback()
End Try