2014-02-26 139 views
1

我很难过,我试图从数据库中填充5个文本框,并非所有5个都会有数据。用ExecuteReader循环遍历行

实施例:

ID | ItemID | QType

1 | 10 | 2盒

2 | 10 | 6盒

3 | 11 | 1案例

在这个例子中,它将填充QuantityType1TxtBox与2 Boxes和QuantityType2TxtBox与6 Boxes,而其他三个文本框留空。

当我尝试运行此代码时,出现以下错误:索引超出了数组的范围。

此错误发生在此行上:QuantityType2TxtBox.Text = rdr.GetString(1);

SqlCommand cmd = new SqlCommand(@"SELECT QType FROM InventoryQType 
               WHERE ItemID = '" + itemID + "'", conn); 
conn.Open(); 
SqlDataReader rdr = cmd.ExecuteReader(); 

while (rdr.Read()) 
{ 
    QuantityType1TxtBox.Text = rdr.GetString(0); 
    QuantityType2TxtBox.Text = rdr.GetString(1); 
    QuantityType3TxtBox.Text = rdr.GetString(2); 
    QuantityType4TxtBox.Text = rdr.GetString(3); 
    QuantityType5TxtBox.Text = rdr.GetString(4); 
} 
rdr.Close(); 
+0

您的数据中只有一个字段,所以GetString(0)之后的任何内容都不应起作用。 – LarsTech

+0

您是否期望获得5条记录? –

+2

另外,总是使用参数来避免sql注入。您的ItemID应该使用您传递值的参数。 – LarsTech

回答

7

我不确定我的switch语句是否正确地做到这一点,但我认为这段代码的其余部分对于向您显示参数和使用语句很有用。

string sql = @"SELECT QType FROM InventoryQType WHERE [email protected]"; 
using (SqlConnection conn = new SqlConnection("[put your connection string here, or reference to web.config]")) { 
    conn.Open(); 
    using (SqlCommand cmd = new SqlCommand(sql, conn)) { 
     cmd.Parameters.Add("@id", System.Data.SqlDbType.VarChar).Value = itemID; 
     SqlDataReader rdr = cmd.ExecuteReader(); 
     int loop = 1; 
     while (rdr.Read()) { 
      switch(loop){ 
       case 1: 
        QuantityType1TxtBox.Text = (string)rdr["QType"]; 
        break; 
       case 2: 
        QuantityType2TxtBox.Text = (string)rdr["QType"]; 
        break; 
       case 3: 
        QuantityType3TxtBox.Text = (string)rdr["QType"]; 
        break; 
       case 4: 
        QuantityType4TxtBox.Text = (string)rdr["QType"]; 
        break; 
       case 5: 
        QuantityType5TxtBox.Text = (string)rdr["QType"]; 
        break; 
       default: 
        break; 
      } 
      loop++; 
     } 
    } 
    conn.Close(); 
} 

此外值得注意的是,您的itemID似乎是您的示例中的varchar。我假设它实际上是一个int,所以如果这是真的,你需要将参数的'VarChar'部分改为'Int'。

+0

这很好,我不得不在那里添加ExecuteReader,但除此之外,工作就像一个魅力。我现在正在将我的所有参数切换到参数。感谢您的提示,我非常感谢。 – techora

+0

哎呀,在ExecuteReader上很好的捕捉。我为未来的观众添加了这个例子。祝你好运! – JClaspill

2

您使用的检索数据的SQL查询只返回QType领域,因此SqlDataReader中只有1列。

因为您通过调用rdr.GetString(1)来请求第二列,所以会出现索引超出范围异常。

我会编辑你的select语句来命名每个你想放在每个文本框中的字段,这样索引就可以像你期望的那样工作。最后,如果您使用上面的代码检索多于一行的数据,则在此方法结束时,文本框将包含最后一条记录的数据 - 这是因为您之前的记录会被覆盖,因为您重复分配每个文本框的Text属性。

0

修正你的代码是这样的:

var values = new List<string>(); 
while (rdr.Read()) 
{ 
    values.add(rdr.GetString(0)); 
} 
3

很多方法可以做到这一点,但原油的实现,让你开始可能看起来像:

List<string> values; 
while(rdr.Read()) 
{ 
    values.Add(rdr.GetString(0)); 
    if (values.Count == 5) break; 
} 

if (values.Count > 0) QuantityType1TxtBox.Text = values[0]; 
if (values.Count > 1) QuantityType2TxtBox.Text = values[1];  
if (values.Count > 2) QuantityType3TxtBox.Text = values[2]; 
if (values.Count > 3) QuantityType4TxtBox.Text = values[3]; 
if (values.Count > 4) QuantityType5TxtBox.Text = values[4]; 

你可能要考虑( a)将你的数据访问代码分离成一个单独的返回值列表的类/方法,(b)将你的文本框放入一个集合中,这样你就不需要重复的代码来为它们赋值。