我正在开发一款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();
}
数据库包含以下数据:
好的,所以你可以看到我更改了WHERE
语句以使用阅读列仅用于测试目的。当我在文本框中输入“111”并运行 - >它只返回行where reading ="1111"
而不返回包含“111”的行。
如果我输入“1111”,则不会返回任何数据。
如果我输入“1”,它将返回“1111”行和“111”行,这是正确的行为。
但是,如果我输入“11”,它再次只返回“1111”行。
尝试返回这些行的2或9的任何其他数据条目都不起作用。
我不确定发生了什么事?这没有任何意义。它的表现不像我期望的任何形状或形式。我知道这一定有点令人困惑。我希望得到一些答案足够的意义。请帮忙!
注意:我在文本之前和之后添加了“%”以尝试获得更好的结果。这是不希望的。
编辑<<< -----------------------我确实有阅读= @Barcode,我只是意外地输入了这个问题的位置,这不是问题。
答案 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";
您正在比较错误的列。