首页 > 解决方案 > SQL 返回不正确的行数

问题描述

我正在尝试使用 SQL 命令并使用 datareader 从我的 MS Access 数据库中获取 2 行数据,但它只返回一行数据。我不完全知道数据读取器是如何工作的,所以我认为这可能是我用它错误编码的东西。SQL 命令应该没问题,因为当我在 MS Access Query 中运行它时它可以工作。你知道我的代码有什么问题吗?[编辑:我实际上并没有尝试获取行数,这只是为了测试。在我发布的代码片段下面,我的程序实际上将数据加载到一个数组中,以便可以比较 2 个整数并选择最小的一个。]

if (passageID != 1)
        {
            Connect(fileName);

            OleDbCommand com = new OleDbCommand();
            com.Connection = cxn;
            com.CommandText = "SELECT PO.OptionID_FK FROM PassageOption AS PO WHERE PO.PassageID_FK = @passageID;";
            com.Parameters.AddWithValue("@passageID", passageID);


            OleDbDataReader r = com.ExecuteReader();

            int numRows = r.RowCount;

            if (r.HasRows)
            {
                int i = 0;
                int[] optionIDs = new int[2];

                while (r.Read())
                {
                    optionIDs[i] = (int)r[i]; // It gives me the following error, the second time it runs, when i = 1; System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'
                    i++;
                }

                if (optionIDs[0] < optionIDs[1])
                {
                    j = optionIDs[0];
                }
                else
                {
                    j = optionIDs[1];
                }
            }
        }

标签: c#sqloledbdatareader

解决方案


数据读取器不知道您的选择查询将返回多少行,直到它从来自数据库的基础流中读取所有数据。

FieldCount 属性返回查询中的字段数,它恰好是您当前查询的字段数。

要知道您需要一一阅读或使用 DataTable 的行

int numRows = 0;
while(r.Read())
{
    // do your task with the current IDataRecord
    numRows++;
}

Console.WriteLine($"There are {numRows} rows");

或填充数据表

DataTable dt = new DataTable();
dt.Load(com.ExecuteReader());
Console.WriteLine($"There are {dt.Rows.Count} rows");

如果您打算使用返回的数据(在读取器数组或表行数组中),上述两种方法很有用,但如果您只想知道存在多少行,那么它更好(尽管只有两行返回的最小) 将您的查询更改为:

com.CommandText = @"SELECT COUNT(*) FROM PassageOption AS PO 
                    WHERE PO.PassageID_FK = @passageID;";
com.Parameters.AddWithValue("@passageID", passageID);
int numRows = (int)com.ExecuteScalar();

当您想要一行有一个字段时不需要阅读器,只需 ExecuteScalar

编辑以更新您的上次编辑

这条线失败

optionIDs[i] = (int)r[i]; 

因为您的查询中只有一个字段。索引器 i 应仅用于引用 optionIDs 数组,而不是从阅读器中提取位置 1 的字段。位置 1 没有字段,只需使用

optionIDs[i] = (int)r[0]; 

对于每个读取调用


推荐阅读