SQL Server CE ГДЕ оператор ведет себя неправильно?очень смущенный - PullRequest
1 голос
/ 06 января 2012

Я занимаюсь разработкой приложения для Windows Mobile.Сейчас я просто тестирую, что он может правильно запрашивать локальную базу данных SQL Server CE.Он работает нормально, пока я не вставлю оператор WHERE.

Вот мой код:

private void buttonStart_Click(object sender, EventArgs e)
{
   System.Data.SqlServerCe.SqlCeConnection conn = new System.Data.SqlServerCe.SqlCeConnection(
   ("Data Source=" + (System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase), "ElectricReading.sdf") + ";Max Database Size=2047")));

   try
   {
       // Connect to the local database
       conn.Open();
       System.Data.SqlServerCe.SqlCeCommand cmd = conn.CreateCommand();

       SqlCeParameter param = new SqlCeParameter();
       param.ParameterName = "@Barcode";
       param.Value = "%" + textBarcode.Text.Trim() + "%";

       // Insert a row
       cmd.CommandText = "SELECT * FROM Main2 WHERE Reading LIKE @Barcode";
       cmd.Parameters.Add(param);

       cmd.ExecuteNonQuery();

       DataTable data = new DataTable();

       using (SqlCeDataReader reader = cmd.ExecuteReader())
       {
           if (reader.Read())
           {
              data.Load(reader);
           }
       }

       if (data != null)
       {
           this.dataGrid1.DataSource = data;
       }
   }
   finally
   {
       conn.Close();
   }

База данных содержит эти данные:

db

Хорошо, вы можете видеть, что я изменил оператор WHERE, чтобы использовать столбец «Чтение» только для целей тестирования.Когда я ввожу «111» в текстовое поле и запускаю -> он возвращает только строку where reading ="1111", а не строку, содержащую «111».

Если я введу «1111», он не вернет никаких данных.

Если я введу «1», он вернет и строку «1111», и строку «111», что является правильным поведением.

Однако, если я введу «11», это только еще развозвращает строку «1111».

Любая другая запись данных из попыток 2 или 9 вернуть эти строки не работает.

Я не уверен, что происходит?Это не имеет никакого смысла.Это не ведет себя так, как я ожидал бы в любом случае, форме или форме.Я знаю, что это должно быть немного запутанным, чтобы читать.Я надеюсь, что имеет смысл получить ответы на некоторые вопросы.Пожалуйста, помогите!

ПРИМЕЧАНИЕ. Я добавил «%» до и после текста, чтобы получить лучший результат.Это не желательно.

РЕДАКТИРОВАТЬ <<< ----------------------- У меня было Чтение = @ Баркод, я просто случайно набрал Location для этого вопроса,это не проблема. </p>

Ответы [ 2 ]

5 голосов
/ 06 января 2012

Во-первых, некоторые вещи, на которые следует обратить внимание:

1) Как отметили другие комментаторы, используйте столбец «Чтение», а не столбец «Местоположение».Я знаю, что вы упомянули, что тестируете, но поменять местами имена столбцов и затем изменить код - не самый простой способ устранения этих проблем.Попробуйте изменить только одну вещь за раз.

2) Если чтение является числовым, вам придется преобразовать значение столбца в первую очередь.

Таким образом, ваш запрос становится:

"SELECT * FROM Main2 WHERE CONVERT(varchar, Reading) LIKE @Barcode";

Также см. Как использовать параметр с LIKE в Sql Server Compact Edition для получения дополнительной помощи по работе с параметрами в SqlServerCE.

3) Установите тип параметра для вашего SqlCEParameter.Я привел ссылку на соответствующую страницу в приведенном ниже примере кода.

4) Вы используете ExecuteNonQuery без причины.Просто избавьтесь от этого в этом контексте.Это когда вы хотите внести изменения в базу данных (например, вставить, обновить, удалить) или выполнить что-то (например, сохраненный процесс, который также может вставлять, обновлять, удалять и т. Д.), Который не возвращает никаких строк.Возможно, вы вырезали и вставили этот код из другого места в вашем приложении: -)

5) Используйте , используя на одноразовых предметах (см. Пример ниже).Это сделает управление жизненным циклом вашего соединения намного проще.Он также более читабелен (IMO) и позаботится о проблемах при возникновении исключений.

6) Используйте оператор using для импорта BCL (библиотеки базовых классов) в текущее пространство имен:

Добавьте следующие операторы использования в начало вашего класса (.cs).Это значительно упростит использование всех классов .Net (и будет намного легче читать и меньше изнашивать вашу клавиатуру; -)

using System.Data.SqlServerCe;
using System.IO;
using System.Reflection;

Более полный пример будет выглядеть следующим образом

private void buttonStart_Click(object sender, EventArgs e) 
{ 
   using(SqlCeConnection conn = new SqlCeConnection( 
   ("Data Source=" + (Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase), "ElectricReading.sdf") + ";Max Database Size=2047"))))
   {

       // Connect to the local database 
       conn.Open(); 
       using(SqlCeCommand cmd = conn.CreateCommand())
       {
       SqlCeParameter param = new SqlCeParameter(); 
       param.ParameterName = "@Barcode"; 
       param.DBType = DBType.String; //Intellisense is your friend here but See http://msdn.microsoft.com/en-US/library/system.data.sqlserverce.sqlceparameter.dbtype(v=VS.80).aspx for supported types
       param.Value = "%" + textBarcode.Text.Trim() + "%"; 

       // SELECT rows
       cmd.CommandText = "SELECT * FROM Main2 WHERE CONVERT(varchar, Reading) LIKE @Barcode";
       cmd.Parameters.Add(param); 

       //cmd.ExecuteNonQuery();  //You don't need this line

       DataTable data = new DataTable(); 

       using (SqlCeDataReader reader = cmd.ExecuteReader()) 
       { 
          data.Load(reader); //SqlCeDataReader does not support the HasRows property.
          if(data.Rows.Count > 0)
          {
              this.dataGrid1.DataSource = data;
          } 
       } 

       }
   }


} 

Intellisense должен быть в состоянии устранить любые ошибки с помощью вышеприведенного, но не стесняйтесь обращаться за дополнительной помощью.

Наконец, вы также можете установить источник данных сетки непосредственно насчитыватель данных, попробуйте!

       using (SqlCeDataReader reader = cmd.ExecuteReader()) 
       { 
          dataGrid1.DataSource = reader; 
       } 

Затем вы можете избавиться от DataTable.

1 голос
/ 06 января 2012

Измените следующую строку:

cmd.CommandText = "SELECT * FROM Main2 WHERE Location LIKE @Barcode";

на

cmd.CommandText = "SELECT * FROM Main2 WHERE Reading LIKE @Barcode";

Вы сравниваете неправильные столбцы.

...