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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: MySql не возвращает результат запроса в C#  (Прочитано 29789 раз)
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 » 

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

Но, тем не менее, мне кажется более правильным, когда при неизвестной цене значение соотв. поля "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 » new

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

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

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines