SQL Server CE WHERE语句行为错误?非常困惑

时间:2012-01-05 21:35:32

标签: c# sql sql-server-ce where-clause

我正在开发一款Windows移动应用。现在我只是测试它可以正确查询本地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的任何其他数据条目都不起作用。

我不确定发生了什么事?这没有任何意义。它的表现不像我期望的任何形状或形式。我知道这一定有点令人困惑。我希望得到一些答案足够的意义。请帮忙!

注意:我在文本之前和之后添加了“%”以尝试获得更好的结果。这是不希望的。

编辑<<< -----------------------我确实有阅读= @Barcode,我只是意外地输入了这个问题的位置,这不是问题。

2 个答案:

答案 0 :(得分:5)

首先,有些事情需要注意:

1)正如其他评论员所指出的那样,使用阅读栏,而不是位置栏。我知道你已经提到过你正在测试,但是更换列名然后更改代码并不是解决这些问题的最简单方法。尽量一次只改变一件事。

2)如果Reading是数字,则首先必须convert列值。

所以你的查询变为:

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

另请参阅How to use parameter with LIKE in Sql Server Compact Edition以获取有关在SqlServerCE中使用参数的更多帮助。

3)在SqlCEParameter上设置参数类型。我已经链接到下面代码示例中的相应页面。

4)您无缘无故地使用ExecuteNonQuery。在这种情况下摆脱它。它适用于您希望对数据库进行更改(如插入,更新,删除)或执行某些不返回任何行的内容(如存储过程,也可以插入,更新,删除等)。您可能已从应用中的其他位置剪切并粘贴此代码: - )

5)在一次性物品上使用using(参见下面的示例)。这将使管理您的连接生命周期变得更加简单。它也更具可读性(IMO),并在发生异常时处理问题。

6)使用using语句将BCL(基类库)导入当前命名空间:

将以下using语句添加到类的顶部(.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应该能够清除上述任何错误,但随时可以寻求更多帮助。

最后,您也可以将网格的数据源直接设置为datareader,试试吧!

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

然后你可以摆脱DataTable。

答案 1 :(得分:1)

更改以下行:

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

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

您正在比较错误的列。