Рейтинг:
5
ZurdoDev
Как уже упоминалось в комментариях, вместо этого используйте ExecuteScalar, так как он возвращает первый столбец первой строки.
А чтобы использовать DataReader, см. Решение 1.
OriginalGriff
Я рад, что вы опубликовали это как решение - это дало мне возможность поднять его!
:большой палец вверх: !
Patrick Skelton
Одна из проблем, с которой я сталкиваюсь с ExecuteScalar (), заключается в том, что при первом запуске на пустой базе данных я не получаю null. Я получаю объект, который просто показывает пустой набор скобок в отладчике. Я не уверен, что это такое или, что более важно, что если () оператор я могу написать, чтобы поймать этот первый запуск.
ZurdoDev
Объект temp = cmd.Executescalar так();
if (temp != null){
Строка jobNo = temp.Метод toString();
}
Patrick Skelton
Боюсь, что это не сработает. Я тестирую против null, получаю false, но затем получаю исключение, когда пытаюсь привести результат к int. Нужно ли мне тестировать DbNull или что-то в этом роде? (Как вы, без сомнения, поняли, я не эксперт по SQL.)
ZurdoDev
Что является результатом темп.Метод toString()?
Patrick Skelton
Используя следующий код:
if (result != null )
{
строка s = (строка)результат;
int x = 10;
}
..Я не могу добраться до точки останова при присвоении x, потому что приведение к строке вызывает исключение.
Patrick Skelton
Ах ... следующие работы:
if (result != DBNull.Ценность )
{
...
}
Спасибо за вашу помощь.
ZurdoDev
То, что я выложил, должно было сработать. Наверное,мне нужно было бы увидеть код, который присваивает результат.
Но рад, что это работает.
Patrick Skelton
Код на самом деле разделен между несколькими вспомогательными функциями, но, собрав его вместе и убрав проверку ошибок, он выглядит так:
SQLiteDataStore.Соединение.Открыть();
string sqlScript = " SELECT max (enquiry_job_number ) FROM EnquiryJobs;";
SQLiteCommand sqlCommand = new SQLiteCommand( sqlScript, SQLiteDataStore.Соединение );
результат объекта = sqlCommand.Executescalar так();
если( результат != нуль &амп;&амп; результат != Значение dbnull.Ценность )
{
// По крайней мере одна запись в БД.
}
ещё
{
// Нет записей в БД.
}
ZurdoDev
Хмм. Должно быть, это как-то связано с SqlLite, потому что я проверяю только null, и это всегда работает. Если что-то действительно вернется как DBNull.Стоимость вызова toString() дает пустую строку.
Во всяком случае, это работает, и это самое главное.
Patrick Skelton
К сожалению, я заговорил слишком рано. Теперь у меня есть подход ремня и подтяжек, показанный ниже. Когда управление проходит мимо моего оператора over-the-top if (), отладчик показывает допустимое положительное целое число; однако, когда я выполняю приведение, я получаю недопустимое исключение приведения. У кого-нибудь есть какие-нибудь идеи, что может произойти? Думаю, что, возможно, придется попробовать метод executenonquery и вместо заявленного подхода колонны. Я просто не появляются, чтобы быть в состоянии сделать что-нибудь надежное с результатом executescalar так.
SQLiteDataStore.Соединение.Открыть();
string sqlScript = " SELECT max (enquiry_job_number ) FROM EnquiryJobs;";
SQLiteCommand sqlCommand = new SQLiteCommand( sqlScript, SQLiteDataStore.Соединение );
результат объекта = sqlCommand.Executescalar так();
если( результат != нуль &амп;&амп; результат.ToString() != Строка.Пустой& & amp; результат != DBNull.Ценность )
{
// По крайней мере одна запись в БД; отладчик показывает положительный int, но следующее приведение дает исключение. :(
int resultAsInteger = (int)результат;
}
ещё
{
// Нет записей в БД.
}
ZurdoDev
Какое значение показывает результат в окне просмотра?
Patrick Skelton
Он показывает действительное положительное целое число.
Patrick Skelton
Он показывает (с каждой строкой, вложенной в ту, что выше):
результат {} объект {система.Значение dbnull}
Статический член
Ценность {} Система.Значение dbnull
На самом деле, теперь, когда вы заставили меня написать его, я вдруг понял, как, черт возьми, он проходит мимо моего оператора if (), если значение равно DBNull? Это означает, что у меня есть два разных значения для DBNull. Можно ли тестировать DBNull со стандартным оператором'=='?
Patrick Skelton
О, подожди. Я перепутал два варианта использования. Когда возвращаемое значение является допустимым числом, его тип - "long", что объясняет недопустимое приведение. Дох! Моя глупая ошибка. Спасибо,что позволил мне отскочить от тебя. В противном случае я потратил бы гораздо больше времени, добираясь до результата.
ZurdoDev
Рад это слышать.
Рейтинг:
14
OriginalGriff
В дополнение к превосходному предложению Ряндева, стоит также отметить, что если вы используете этот SQL:
SELECT max( enquiry_job_number ) FROM EnquiryJobs;
Вы не можете получить доступ к данным из DataReader, как это:
SQLiteDataReader.GetOrdinal( columnName )
Потому что вы вообще не дали столбцу данных имени.
В будущем попробуйте назвать столбец, когда вы его вернете:
SELECT max( enquiry_job_number ) AS MaxJobNo FROM EnquiryJobs;
И вы можете получить доступ к столбцу по имени:
int max = (int) myDataReader["MaxJobNo"];
Patrick Skelton
Спасибо тебе за это. Обычно я называю возвращаемые значения. Я ошибочно предположил, что имя будет таким же, как и имя столбца.
OriginalGriff
Не тогда, когда вы применяете агрегатную функцию!