Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: MySql не возвращает результат запроса в C#  (Прочитано 25747 раз)
0 Пользователей и 1 Гость смотрят эту тему.
h.m.f.
Участник

ru
Offline Offline
Пол: Мужской

« : 03-04-2006 10:55 » 

При попытке прочитать результат запроса возникает исключение: "An unhandled exception of type 'System.NullReferenceException' occurred in mysql.data.dll Additional information: В экземпляре объекта не задана ссылка на объект.":

MySqlCmd.CommandText="select ... ";
MySqlReader=MySqlCmd.ExecuteReader();
while(MySqlReader.Read())
{Price=MySqlReader.GetFloat(2);}   

Причем при установлении брякпойнтов на эту часть кода он работает, если скопировать текст MySqlCmd из окна отладки в MySql то выводится единственная запись
« Последнее редактирование: 16-12-2007 17:24 от Алексей1153++ » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 03-04-2006 11:22 » 

Я с C# API не работал, но по аналогии с другими языками, для которых есть mysql API, результирующий набор возвращается только при удавшихся запросах типа SELECT, SHOW, DESCRIPT. Короче, если данные должны быть, то надо проверять, есть ли они реально.
« Последнее редактирование: 03-04-2006 15:10 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Mouse
Молодой специалист

ru
Offline Offline

« Ответ #2 : 03-04-2006 14:58 » 

h.m.f., а сколько у тебя столбцов в результирующей таблице? Если ты хочешь взять значение 2-го столбца, то это не прокатит, индекс-то, кажется, с нуля начинается Ага
Кстати, а Connection.Open() не забыл перед этим сделать?
Если все это не то, то давай полный листинг функции, работающей с БД, текст SQL запроса и результат его выполнения в MySQL - разберемся Улыбаюсь
Записан
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #3 : 04-04-2006 04:21 » 

Если ты хочешь взять значение 2-го столбца, то это не прокатит, индекс-то, кажется, с нуля начинается Ага
Конечно с нуля Улыбаюсь Но в таком случае скорее всего сгенерился бы Index overflow exception, хотя не факт.
h.m.f., чтобы поймать эксепшн, возьми код в try .. catch

Код:
try{
      MySqlCmd.CommandText="select ... ";
      MySqlReader=MySqlCmd.ExecuteReader();
      while(MySqlReader.Read())
      {Price=MySqlReader.GetFloat(2);}   
}
catch(System.Exception ex)
{
      MessageBox.Show(ex.Message);
}

Ну и код в студию не помешал бы Улыбаюсь
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
h.m.f.
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 04-04-2006 07:49 » 

Оказалось, что столб содержит в некоторых строках значение null, а я в mysql проверял запрос для брякпойнта предыдущей итерации (кусок кода, который я напечатал находится внутри цикла).

В связи с чем возникает еще один вопрос: как переменной присвоить значение null, если в mysql записан null? (т.е. даже как понять null там или нет без обработки исключений (где-то читал что вызов эксепшена весьма пагубно влияет на производительность а у меня примерно 150 000 строк с нулями)
Можно конечно обрабатывать таблицу несколькими запросами когда price is null, price is not null, но если у меня будет в 20 столбах встречаться null...
Записан
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #5 : 04-04-2006 07:56 » 

Хммм....
Я бы посоветовал бы тебе все null обрабатывать в самом запросе и заменять на нужные значения.
Например если интеджер, то заменить на 0 и так далее...
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #6 : 04-04-2006 08:44 » 

для столбцов, где может быть NULL используй или DECODE или IFNULL и задавай значение сам 0 или "" (в зависимости от типа столбца)
Записан

Удачного всем кодинга! -=x[PooH]x=-
Mouse
Молодой специалист

ru
Offline Offline

« Ответ #7 : 04-04-2006 08:54 » 

SQL запрос трогать не надо, проверку на NULL делай в программе примерно так:

Код:
if (reader.IsDBNull(2))
{
  Price = reader.GetFloat(2);
}
else
{
  Price = -1;
}
Записан
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #8 : 04-04-2006 08:58 » 

SQL запрос трогать не надо, проверку на NULL делай в программе примерно так:

Код:
if (reader.IsDBNull(2))
{
  Price = reader.GetFloat(2);
}
else
{
  Price = -1;
}

ИМХО как раз таки в самом запросе будет быстрее нежели куча ифов.
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Mouse
Молодой специалист

ru
Offline Offline

« Ответ #9 : 04-04-2006 09:05 » 

MOPO3, если и быстрее, то не намного. Запрос должен возвращать данные из БД, чем он и занимается. Интерпретация этих данных - дело клиентского приложения. Хотя это уже идеологичекий вопрос, каждый для себя сам решает Улыбаюсь Ближе к вечеру проведу эксперимент по быстродействию, как будет готово выложу результаты. Самому интересно стало Улыбаюсь
Записан
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #10 : 04-04-2006 09:16 » 

Согласен Улыбаюсь Тут дело вкуса Улыбаюсь
Но ИМХО для красоты и краткости кода, сделать проверку в запросе всё же лучше было бы Улыбаюсь

Запрос должен возвращать данные из БД, чем он и занимается. Интерпретация этих данных - дело клиентского приложения.

Вот тут позволь не согласиться Улыбаюсь Правильно сформированый запрос с выборкой и интерпретацией данных позволит избежать запарок в последующем програмном разборе этих данных.

Я всё же уверен что встроеные SQL функции всё же быстрее отработают нежели проверка на каком-нибудь АПИ к данной базе Ага
Хотя опять же всё зависит от правильного проектирования базы, а также от написания хорошего кода Улыбаюсь
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Mouse
Молодой специалист

ru
Offline Offline

« Ответ #11 : 04-04-2006 09:25 » new

Ну так чего спорить на пустом месте, как будет время подгоню реальные результаты Ага

Но, тем не менее, мне кажется более правильным, когда при неизвестной цене значение соотв. поля "is NULL", а не "= -1". Все-таки в последнем варианте мы имеем известную цену, равную "-1". Удобнее всасывать данные на клиенте - безусловно. Ладно, поглядим на реальную разницу во времени...
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 04-04-2006 13:01 » 

Стойства поля все равно передаются от сервера клиенту. В памяти это просто число, используемой как набор флагов. Лишний вызов ф-ии я бы не назвал сильно нагружающим. Тут или сервер будет больше нагружен, или клиент. Работа будет выполнена примерно одна. Информации столько же.

Конечно, как делать - решать самому программисту с учетом местных условий и ограничений.

Например, если в выбираемой таблице много столбцов (и нужно их не мало, или нужны все, или состав неизвестный или переменный), то легче обработать на месте, чем перечислять их в запросе.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Mouse
Молодой специалист

ru
Offline Offline

« Ответ #13 : 04-04-2006 15:26 » 

Ну чтож, пример был сделан Улыбаюсь

Таблица Test. Содержит 301000 строк. Не спрашивайте почему 301000, а не 300000 Ага Ну считаю я плохо...  Скромно так...
Код:
CREATE TABLE Test (
[ID] int IDENTITY (1, 1) NOT NULL,
FloatField float NULL
)

1. Обработка данных в приложении
Кусок кода приложения:
Код:
SqlDataReader reader = command.ExecuteReader();

DateTime start = DateTime.Now;

ArrayList arrayList = new ArrayList();
while (reader.Read())
{
if (!reader.IsDBNull(1))
{
arrayList.Add(reader.GetDouble(1));
}
else
{
arrayList.Add(-1);
}
}

reader.Close();

double milliseconds = (DateTime.Now - start).TotalMilliseconds;
milliseconds = 0;
]

При этом в таблице
а) Все строки "is null". При этом выполнение кода занимает примерно 700-750 миллисекунд
б) Каждая третья строка = 0, остальные NULLы. Время выполнения - в среднем 800-850 миллисекунд

2. Обработка данных в СУБД
Как элегантно перевести NULLы в нули прямо в запросе SELECT я не понял, может вы мне подскажете...  Здесь была моя ладья...
Тогда решил сделать задачу попроще - во всей таблице поставил поля "= 0". Здесь, как и везде, поле ID никак не учитывается, вообще оно было введено только "для порядку"  Отлично

Код приложения упростил:
Код:
SqlDataReader reader = command.ExecuteReader();

DateTime start = DateTime.Now;

ArrayList arrayList = new ArrayList();
while (reader.Read())
{
arrayList.Add(reader.GetDouble(1));
}

reader.Close();

double milliseconds = (DateTime.Now - start).TotalMilliseconds;
milliseconds = 0;

Результат меня удивил - 800-850, а то и все 900 с гаком миллисекунд!  Быть такого не может  Получается, что выгоднее обрабатывать NULLы в приложении. Заметьте, что это еще при том, что я не писал замену NULLов на нули в запросе, а просто в БД данные изменил.

Итак, проверки лучше проводить на клиенте, что и требовалось доказать  Улыбаюсь  Еще раз прошу обратить внимание, что в моем примере не производилось преобразование данных в корректный вид базой данных, данные уже были корректными, т.е. NULLов не содержали
« Последнее редактирование: 04-04-2006 15:27 от Mouse » Записан
Mouse
Молодой специалист

ru
Offline Offline

« Ответ #14 : 04-04-2006 15:29 » 

RXL, тут разговор не о количестве столбцов, а об их содержимом. С количеством все понятно, лишние данные таскать не стоит Улыбаюсь
Записан
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #15 : 05-04-2006 04:16 » 

Улыбаюсь
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines