2010-02-26 2 views
0
string queryStr = "select max(patient_history_date_bio) " + 
    "as med_date, medication_name from biological where " + 
    "(patient_id = " + patientID.patient_id + ") " + 
    "group by medication_name;"; 



using (var conn = new SqlConnection(connStr)) 
using (var cmd = new SqlCommand(queryStr, conn)) 
{ 
    conn.Open(); 

    using (SqlDataReader rdr = cmd.ExecuteReader()) 
    { 
     int count = 0; 

     while (rdr.Read()) 
     { 
      MessageBox.Show("test"); 
      med.medication_date[count] = new DateTime(); 

      med.medication_date[count] = DateTime.Parse(rdr["med_date"]. 
       ToString()); 

      MessageBox.Show("test2"); 

      med.medication_name[count] = rdr["medication_name"].ToString(); 

      count++; 
     } 
    } 

    conn.Close(); 
} 

поэтому я пытаюсь прочитать это заявление sql. Отображается окно сообщения «тест», но не «test2». Я попробовал запустить инструкцию sql в VS самостоятельно (в проводнике сервера), и инструкция sql работает. это дает мне то, что я хочу. но почему-то код не работает ... кто-нибудь видит, почему?пытается прочитать инструкцию sql C#

ответ

3

Предполагая, что patient_id является своего рода целым числом (или это Guid), я полагаю, что текущая культура вашей программы вызывает вызов метода ToString для int для форматирования таким образом, который возвращает то, что синтаксический анализатор не может разбираться (например, «1,234,567»).

Как правило, то, как вы выполняете это утверждение, не является лучшей практикой. Хотя вы не можете быть восприимчивы к injection attacks, если id действительно является int (вы определенно открыты для них, если это строка), вы обычно хотите параметризовать запросы.

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

Еще одна вещь, указывающая на ваш код, - это то, как вы извлекаете значения из читателя. Вы эффективно вызываете ToString в экземпляре DateTime, а затем вызываете Parse в строке, чтобы вернуть DateTime.

Это эффективно сжигает циклы. Все, что вам нужно сделать, это бросить (unbox в случае типов значений) значение обратно.

Так где у вас есть:

med.medication_date[count] = DateTime.Parse(rdr["med_date"]. 
    ToString()); 

Вы должны иметь:

med.medication_date[count] = (DateTime) rdr["med_date"]; 

Все, как говорится, о том, почему второе окно сообщения не отображается, мое первое предположение, что вы выполняя это в обработчике событий в приложении Windows Forms и создавая исключение.

Я думаю, что вы обнаружите, что если medication_date является массивом, то он не был инициализирован, и вы получаете исключение NullReferenceException или что-то о том, что индекс массива выходит за рамки.

+0

Если это так, почему первый дисплей сообщений, а не второй? –

+0

@ Митч Пшеница: см. Обновленный ответ. – casperOne

+0

больше похоже новый ответ! ;) Кстати, это был риторический вопрос. –

0

Что такое med.medication_date?

Если это массив, возможно, он еще не инициализирован. Если это список, вы должны назначить ему, используя med.medication_date.Add(value);

В качестве альтернативы, как и все остальные, может произойти ошибка преобразования даты. Попробуйте заменить

MessageBox.Show("test"); 

С

MessageBox.Show(rdr["med_date"].ToString()); 
0

Без дополнительной информации, это выглядит как линия

med.medication_date[count] = DateTime.Parse(rdr["med_date"].ToString()); 

генерирует исключение из-за непризнанную дату, и исключение, проглоченное обработчик выше.

0

Вы должны направить свои файлы отладки в окно вывода ... это легче, чем следить за потоком.

  system.diagnostics.debug.writeline(rdr["med_date"].ToString()); 
Смежные вопросы