SQL возвращает неверное количество строк - PullRequest
0 голосов
/ 11 мая 2018

Я пытаюсь получить 2 строки данных из моей базы данных MS Access с помощью команды SQL и с помощью устройства чтения данных, но он возвращает только одну строку данных. Я точно не знаю, как работает хранилище данных, поэтому я думаю, что это может быть из-за того, что я неправильно кодировал его. Команда SQL должна быть в порядке, потому что когда я запускаю ее в MS Access Query, она работает. Вы знаете, что не так с моим кодом? [Edit: я на самом деле не пытаюсь получить количество строк, это просто для тестирования. Ниже фрагмента кода, который я разместил, моя программа фактически загружает данные в массив, чтобы можно было сравнить 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];
                }
            }
        }

Ответы [ 3 ]

0 голосов
/ 11 мая 2018

Устройство чтения данных не знает, сколько строк будет возвращено вашим запросом select, пока не прочитает все данные из базового потока, поступающего из базы данных.

Свойство FieldCount возвращает количество полей в вашем запросе, и оно равно одному для вашего текущего запроса.

Чтобы узнать строки, вам нужно прочитать их одну за другой или использовать DataTable

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

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

Или заполнение DataTable

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

за каждый прочитанный звонок

0 голосов
/ 11 мая 2018

Ваш считыватель данных содержит только один столбец, выбранный вами, PO.OptionID_FK. Поэтому в вашем цикле, когда i равно 1:

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.'

... вы пытаетесь выбрать второй столбец из устройства чтения данных (r[i]), которого не существует.

Способ работы DataReader заключается в том, что всякий раз, когда вы делаете r.read, вы перемещаетесь на следующую строку, и ваша r переменная «массив» обновляется со всеми значениями столбцов из новой строки. Индекс массива r[n] выбирает nth столбец считывателя, а не n-ную строку . Так что вы должны просто использовать:

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

... который установит ваше значение optionIDs со значением первого (нулевого) столбца DataReader для текущей строки.

0 голосов
/ 11 мая 2018
int numRows = r.FieldCount;

FieldCount Свойство получает количество столбцов в строке, а не количество записей.

Вы выбираете только OptionID_FK один столбец из таблицы.FieldCount покажет вам 1.

Получение нет.рядов

OleDbDataReader r = com.ExecuteReader();
int rowCount = 0;
if (r.HasRows)  
{  
    while (r.Read())  
    {  
       rowCount++;     
    }  
}
r.Close(); 
...