while循环只显示1项

时间:2013-12-18 19:58:37

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

我正在使用while循环根据第一个组合框选择的值填充第二个组合。然而,正在发生的是,循环只在第二个组合框中显示1个项目,而不是大约20个。如果我在while循环上设置断点,我可以看到所有项目都在计算但只是没有出现在组合框中。

如果有人能指出我的基本新手错误,我将不胜感激。非常感谢

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

2 个答案:

答案 0 :(得分:5)

组合框的Text属性仅包含为所选项目显示的内容。您需要将项目添加到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语句自动调用Using

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

Dispose将在Using块的末尾调用,即使Using块中发生错误或Using块被{{1}留下或另一种陈述。

答案 1 :(得分:4)

您不需要检查数据读取器是否每次迭代都有行,只需在循环之前检查它。

您不是要将项目添加到列表中,而是设置Text的{​​{1}}属性,而是执行此操作:

cmbDept

此外,强烈建议您使用参数化查询以避免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 = '" & 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