简体   繁体   English

使用ExecuteReader遍历行

[英]Looping through rows with ExecuteReader

I'm stumped, I am trying to fill 5 textboxes from a database, not all 5 will always have data. 我很困惑,我试图从数据库中填充5个文本框,但并非所有5个文本框都总是有数据。

Example: 例:

ID | ID | ItemID | ItemID | QType QType

1 | 1 | 10 | 10 | 2 Boxes 2盒

2 | 2 | 10 | 10 | 6 Boxes 6盒

3 | 3 | 11 | 11 | 1 Case 1箱

In this example it would fill QuantityType1TxtBox with 2 Boxes and QuantityType2TxtBox with 6 Boxes, while leaving the other three textboxes blank. 在此示例中,它将用2个Box填充QuantityType1TxtBox并用6个Box填充QuantityType2TxtBox,而其他三个文本框保留为空白。

The following error I get when I try to run this code is: Index was outside the bounds of the array. 当我尝试运行此代码时,出现以下错误: 索引超出数组的范围。

This error happens on this line: QuantityType2TxtBox.Text = rdr.GetString(1); 在此行上发生此错误: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();

I'm not sure my switch statement is the right way to do it for this, but I think the rest of this code is useful to show you parameters and using statements. 我不确定我的switch语句是执行此操作的正确方法,但是我认为这段代码的其余部分对于向您展示参数和使用语句很有用。

string sql = @"SELECT QType FROM InventoryQType WHERE ItemID=@id";
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();
}

Also of note, your itemID seems to be a varchar in your example. 还要注意的是,您的itemID在您的示例中似乎是varchar。 I assume it is actually an int, so you'll need to change the 'VarChar' part of the Parameter to be 'Int' if that is true. 我假设它实际上是一个int,因此,如果为true,则需要将Parameter的“ VarChar”部分更改为“ Int”。

Lots of ways to do this, but a crude implementation to get you started might look something like: 有很多方法可以做到这一点,但是粗略的实现可以让您入门:

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];

You might want to consider (a) separating your data access code into a separate class / method that returns a list of values, and (b) putting your text boxes into a collection so you don't need repeated code to assign values to them. 您可能需要考虑(a)将数据访问代码分为返回值列表的单独的类/方法,以及(b)将文本框放入集合中,因此您无需重复的代码即可为它们分配值。

The SQL query you are using to retrieve the data only returns the QType field, so the SqlDataReader only has 1 column. 您用于检索数据的SQL查询仅返回QType字段,因此SqlDataReader仅具有1列。

Because you are requesting the second column by calling rdr.GetString(1) , an Index out of bounds exception occurs. 因为您通过调用rdr.GetString(1)请求第二列, rdr.GetString(1)发生了索引超出范围异常。

I would edit your select statement to name each of the fields you would like to put in each text box, so that the indexing would work as you expect. 我将编辑您的select语句,以命名要在每个文本框中输入的每个字段,以便索引可以按预期工作。

Finally, if you retrieve more than 1 row of data with the code above, at the end of this method the text boxes would contain the data from the last record - this is because the previous records would be overwritten, since you are assigning the Text property of each text box repeatedly. 最后,如果使用上面的代码检索了多于一行的数据,则在此方法的结尾,文本框将包含来自最后一条记录的数据-这是因为先前的记录将被覆盖,因为您正在分配Text每个文本框的属性重复。

Fix your code like this: 像这样修复您的代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM