2013-12-18 137 views
0

我正在使用while循環根據第一個組合框的選擇值填充第二個組合。然而,正在發生的事情是,循環只在第二個組合框中顯示1個項目,而不是大約20個。如果我在while循環中設置斷點,我可以看到所有項目正在計算中,但沒有出現在組合框中。while循環只顯示1個項目

如果有人能指出我的基本新手錯誤,我將不勝感激。非常感謝

Private Sub cmbCustomer_SelectedIndexChanged(ByVal sender As System.Object, _ 
              ByVal e As System.EventArgs) _ 
    Handles cmbCustomer.SelectedIndexChanged 

    sql = "SELECT * from Departments WHERE Customer = '" & cmbCustomer.Text & "'" 

    Dim cmd As New OleDb.OleDbCommand 

    cmd.CommandText = sql 
    cmd.Connection = oledbCnn 
    dr = cmd.ExecuteReader 

    While dr.Read() 
     If (dr.HasRows) Then 
      cmbDept.Text = CStr((dr("Name"))) <--- 2nd combobox 
     End If 
    End While 

    cmd.Dispose() 
    dr.Close() 
End Sub 
+1

剛剛看到我的錯誤。應該是:cmbDept.Items.Add(dr(「Name」)) – user1532468

回答

5

組合框的Text屬性包含只WH at顯示所選項目。您需要將項目添加到收藏Items

cmbDept.Items.Add(CStr(dr("Name"))) 

組合框,列表框等顯示項目通過調用其ToString()方法。因此呼籲CStr甚至不應該是必要的:

cmbDept.Items.Add(dr("Name")) 

您是通過連接字符串中插入SQL語句中的值。如果你只是爲自己使用你的程序,這沒關係;然而,在生產環境中這是危險的。有人可能輸入一個終止SELECT語句的值並引入另一個惡意語句。例如。一個刪除整個表的DELETE語句。這被稱爲SQL注入攻擊。

有兩種方法來處理這個:

1)轉義字符串:

sql = "SELECT * FROM Dep WHERE Cust = '" & s.Replace("'", "''") & "'" 

2)使用命令參數:

sql = "SELECT * from Departments WHERE Customer = ?" 
    Dim cmd As New OleDbCommand(sql, oledbCnn) 
    cmd.Parameters.AddWithValue("@p1", cmbCustomer.Text) 

如果插入日期,這也有一個好處,你不需要打擾日期格式。


您可以簡化環路:

While dr.Read() 
    cmbDept.Text = CStr(dr("Name")) 
End While 

沒有必要測試HasRows因爲dr.Read()將返回False無論如何,如果沒有行可用。


您可以Dispose由VB自動調用與Using聲明:

Using cmd As New OleDbCommand(sql, oledbCnn) 
    'TODO: Work with cmd here. 
End Using 

Dispose將在Using塊的末尾被調用,即使Using塊或內發生錯誤Using塊由Return或其他語句留下。

+0

感謝Oliver的建議。有一件事我有麻煩。當我更改第一個組合框中的值時,而不是更新第二個組合,只是將項目添加到它。是否有刷新或清楚,我必須使用。謝謝 – user1532468

+0

找到了。 cmbDept.Items.Clear()謝謝 – user1532468

4

您不需要檢查數據讀取器是否每次迭代都有行,只是在循環之前檢查它。

您沒有添加項目到列表中,而是設定的cmbDeptText財產,而不是這樣做:

Private Sub cmbCustomer_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbCustomer.SelectedIndexChanged 
    sql = "SELECT * from Departments WHERE Customer = '" & cmbCustomer.Text & "'" 

    Dim cmd As New OleDb.OleDbCommand 

    cmd.CommandText = sql 
    cmd.Connection = oledbCnn 
    dr = cmd.ExecuteReader 

    If (dr.HasRows) Then 
     While dr.Read() 
      cmbDept.Text = CStr((dr("Name"))) <--- 2nd combobox 
     End While 
    End If 

    cmd.Dispose() 
    dr.Close() 
End Sub 

另外,強烈建議您使用參數化查詢作爲以避免進行了訪問Little Bobby Tables,像這樣:

Private Sub cmbCustomer_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbCustomer.SelectedIndexChanged 
    sql = "SELECT * from Departments WHERE Customer = @Customer" 

    Dim cmd As New OleDb.OleDbCommand 
    cmd.Parameters.AddWithValue("@Customer", cmbCustomer.Text) 

    cmd.CommandText = sql 
    cmd.Connection = oledbCnn 
    dr = cmd.ExecuteReader 

    If (dr.HasRows) Then 
     While dr.Read() 
      cmbDept.Text = CStr((dr("Name"))) <--- 2nd combobox 
     End While 
    End If 

    cmd.Dispose() 
    dr.Close() 
End Sub 
+0

您仍然將項目分配給「Text」屬性,而不是將它們添加到「Items」集合。 –