1

В моем коде, когда я отладки с помощью Visual Studio C# я заметил, что, хотя нет строк в запросе:Свойство HasRows в MySqlDataReader C# всегда возвращает истинное значение?

select MAX(idSalesJournal) as maxId from accountingsystemdb.salesjournal" 

в dr.HasRows свойство всегда возвращает значение TRUE. Когда я продолжаю отладку, я заметил, что цикл будет работать один раз перед выходом из цикла. Теперь у меня большая проблема, потому что, хотя в наборе данных нет данных о том, как цикл будет работать 1 раз. Затем я напечатал значение, которое я получил в окне сообщений, и ничего не показывает (пустое). Как это могло случиться и как я могу избежать этого? Я поставлю образ того же запроса, который я выполнил в workbench mySql, который успешно выполнил и не отображал никаких строк в результате. Он показывает 0 строк в MySql. Тот же запрос, выполненный в C#, вернет свойство Hasrows как True. Я поставил полный код ниже.

public void salesJournal(string addOrRemove, string lorryNo, string invoiceNo, DateTime billDate, string source, DateTime paybackDate, string itemCode, double itemcost, string desc, double qty, double discount, double amount, string debtor) 
    { 

     if (conn.State.ToString() == "Open") 
     { 
      conn.Close(); 
      conn.Open(); 
     } 

     int maxID = 0; 

     if (conn.State.ToString() == "Closed") 
     { 
      conn.Open(); 
      MySqlCommand cmd = conn.CreateCommand(); 
      cmd.Connection = conn; 
      cmd.CommandType = CommandType.Text; 

      //---------------------- Selecting Max ID ------------------------------------------ 
      cmd.CommandText = "select MAX(idSalesJournal) as maxId from accountingsystemdb.salesjournal"; 

      try 
      { 
       MySqlDataReader dr = cmd.ExecuteReader(); 

       if (dr.HasRows && dr != null) 
       { 

        while (dr.Read()) 
        {        

         maxID = Convert.ToInt32(dr["maxId"].ToString()); 

        } 
       } 
       else 
       { 
        maxID = 0; 
       } 
      } 
      catch(Exception e) 
      { 
       MessageBox.Show(e.ToString()); 
      } 

      conn.Close(); 
      //--------------------------------------------------------------------------------- 


      if (conn.State.ToString() == "Open") 
      { 
       conn.Close(); 
       conn.Open(); 
      } 
      else 
      { 
       conn.Open(); 
      } 

      try 
      { 
       cmd.CommandText = "insert into accountingsystemdb.salesjournal VALUES('" + maxID + 1 + "', STR_TO_DATE('" + billDate + "', '%m/%d/%Y %h:%i:%s %p'), '" + invoiceNo + "', '" + lorryNo + "', '" + source + "', '" + itemCode + "', '" + desc + "', '" + qty + "', '" + itemcost + "', '" + amount + "', '" + discount + "', '" + addOrRemove + "', STR_TO_DATE('" + paybackDate + "', '%m/%d/%Y %h:%i:%s %p'), '" + debtor + "', '" + Program.username + "')"; 
       cmd.ExecuteNonQuery(); 
      } 
      catch(Exception e) 
      { 
       MessageBox.Show(e.ToString()); 
      } 

      conn.Close(); 

     } 


    } 
+1

Даже будет '0',' MAX' действительно возвращает значение, на мой взгляд. Что ваша команда возвращает в вашем менеджере баз данных? Как вы сказали, ваши «while» петли 1 раз, это означает, что у вас ** есть строка _actually_, и это слишком обычная 'HasRows' возвращает' true'. –

ответ

0

Вместо использования ExecuteReader использования ExecuteScalar

Попробуйте

object countObj = cmd.ExecuteScalar(); 
int maxCount = 0; 
if (countObj != null) 
{ 
    int.TryParse(countObj.ToString(), out maxCount); 
} 
+1

Как это отвечает на вопрос? o.o –

1

Вы используете неправильный инструмент для работы. Предполагается, что DataReader используется для итерации по набору данных, и вы ожидаете вернуть только одно значение (или null).

Правильный метод использования является MySqlCommand.ExecuteScalar

try 
{ 
    var result = cmd.ExecuteScalar(); 

    if (result != null) 
    { 
     maxID = Convert.ToInt32(result); 
    } 
    else 
    { 
     maxID = 0; 
    } 
} 
catch(Exception e) 
{ 
    MessageBox.Show(e.ToString()); 
} 
0

Да. это потому, что, если ничего нет, значение ячейки будет null в SQL SERVER. поэтому текст "NULL" является результатом, возвращаемым в SQLServer.

Лучше использовать dr.read(), чтобы проверить, является ли читатель HasRows

if(dr.read()) 
 
{ 
 
// code logic for HasRows 
 
} 
 
else 
 
{ 
 
// if nothing is there 
 
}

0

Запрос к базе данных MySql может вернуть два набора результатов. Первый набор результатов (aka table) - это количество строк, возвращаемых/затронутых, второе - результаты вашего фактического запроса.

Таким образом, параметр HasRows, установленный в true, является точным, потому что вы читаете первый набор результатов, в котором есть 1 строка, содержащая количество строк, возвращаемых из вашего фактического запроса.

Вызвать dr.NextResult(), чтобы получить фактические результаты запроса.