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

tar*_*058 1 c# sql where-clause sql-server-ce

我正在开发一个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();
   }
Run Code Online (Sandbox Code Playgroud)

数据库包含以下数据:

D b

好的,所以你可以看到我更改了WHERE语句以使用阅读列仅用于测试目的.当我在文本框中输入"111"并运行 - >它只返回行where reading ="1111"而不是包含"111"的行.

如果我输入"1111",它不会返回任何数据.

如果我输入"1",它将返回"1111"行和"111"行,这是正确的行为.

但是,如果我输入"11",它再次只返回"1111"行.

尝试返回这些行的2或9的任何其他数据条目都不起作用.

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

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

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

das*_*ash 5

首先,要注意一些事项:

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

2)如果Reading是数字,则必须首先转换列值.

所以你的查询变成:

"SELECT * FROM Main2 WHERE CONVERT(varchar, Reading) LIKE @Barcode";
Run Code Online (Sandbox Code Playgroud)

另请参阅如何在Sql Server Compact Edition中使用LIKE参数以获取有关在SqlServerCE中使用参数的更多帮助.

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

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

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

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

将以下using语句添加到类的顶部(.cs).这将使所有的.Net类使用起来更简单(并且更容易阅读并且键盘磨损更少;-)

using System.Data.SqlServerCe;
using System.IO;
using System.Reflection;
Run Code Online (Sandbox Code Playgroud)

更完整的示例如下所示

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;
          } 
       } 

       }
   }


} 
Run Code Online (Sandbox Code Playgroud)

Intellisense应该能够清除上述任何错误,但随时可以寻求更多帮助.

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

       using (SqlCeDataReader reader = cmd.ExecuteReader()) 
       { 
          dataGrid1.DataSource = reader; 
       } 
Run Code Online (Sandbox Code Playgroud)

然后,您可以摆脱DataTable.