这种编码是否适合插入2个表格

时间:2014-01-25 19:34:33

标签: vb.net visual-studio-2010 visual-studio

我有一些代码将数据插入到访问数据库中的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

2 个答案:

答案 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