c# - 如何在以特定名称开头的列中查找行?
问题描述
private void button1_Click(object sender, EventArgs e)
{
SqlConnection connection = new SqlConnection(@"Database Login");
connection.Open();
SqlCommand command = new SqlCommand("SELECT * FROM table WHERE row = '" + textBox1.Text + "%' AND row = '%" + textBox2.text + "%'", connection);
SqlDataReader dataReader = command.ExecuteReader();
if (dataReader.Read())
{
textBox3.Text = dataReader.GetString(1);
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
}
例如我有这样的行:
香蕉橙苹果
苹果橙香蕉
橙苹果香蕉
香蕉苹果橙
我需要在 textBox3 中输出答案,例如所有行都从香蕉开始,所以答案将是:
香蕉橙苹果
香蕉苹果橙
但是当我按下按钮时没有任何反应,那么我的错误在哪里,据我所知,我使用 dataReader.Read 错误,也许我的 SQL 代码也错误?
解决方案
简短的回答 - 将您的代码更改为如下所示。请注意 sql 语句使用LIKE
而不是=
因为您想要使用的值只是您正在查找的字符串的一部分。
private string GetDataFromRow(string param)
{
var result = string.Empty;
using (var connection = new SqlConnection(@"Database Login"))
{
connection.Open();
var sql = "SELECT mySpecificColumn FROM table WHERE row LIKE @txt1";
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.Add("@txt1", SqlDbType.VarChar).Value = $"'{param}%'";
using (var dataReader = command.ExecuteReader())
{
var l = new List<string>();
while (dataReader.Read())
{
var data = dataReader.GetString(0);
l.Add(data);
}
result = string.Join(System.Environment.NewLine, l);
}
}
}
return result;
}
假设:
我将假设(基于 OP)“textBox1”中的搜索参数将提供您打算从数据库中检索的值。在您的示例中为“香蕉”。我进一步假设“textBox2”实际上是无关紧要的——至少在提供的示例中是这样。我还假设您希望返回单个列的内容。我将该列称为“mySpecificCoulmn”。请将其替换为您希望从中检索数据的列的实际名称。
代码解释:
首先你会注意到我利用了这些using
块。这很重要,因为它们有助于确保我打开的对象关闭并妥善处理。SqlConnection
,SqlCommand
并且DataReader
都实现了接口——这些对象的IDisposable
良好做法是。好吧,该块会为您解决这个问题。close
dispose
using
接下来你会注意到我使用Parameters
了我的SqlCommand
对象。这有助于防止 SQL 注入。在接受用户输入时使用参数尤为重要。我用过SqlDBType.VarChar
,但你的可能是SqlDBType.NVarChar
或别的。选择适合SqlDBType
您正在搜索的列。
请注意,我在 Sql 语句 (mySpecificColumn) 中只请求了一列,而不是使用“*”。它更简洁、形式更好、更快,最重要的是,让我可以控制从数据库返回数据的方式。
如上所述,我仅使用一个搜索参数,根据您的示例,该参数正在查找部分包含“香蕉”的列中的任何值。所以我使用LIKE
然后添加参数名称“@txt1”。在代码的更下方,我们将 添加Parameter
到“命令”对象中,Value
您会看到我使用插值来添加实际的搜索条件。如果我们将“banana”作为参数传递,那么值Parameter
将是“banana%”,这意味着我们想要一个以“banana”开头的值以及之后的任何内容。
调用ExecuteReader
返回一个我们在循环DataReader
中读取的对象。while
在每个循环中,我们将返回值添加到List
我们在方法顶部声明的字符串中。
最后,使用该string
方法Join
将List
值连接起来以创建一个字符串,该字符串由新行分隔以匹配您所需的输出:
banana-orange-apple
banana-apple-orange
注意:
由于数据库查询可能需要时间并阻塞 UI,我强烈建议您考虑使用上述Async
方法的版本使您的代码异步。由于这是一个高级主题,我不会详细介绍,而只是提供Async
上面代码的替代版本。
private async Task<string> GetDataFromRowAsync(string param)
{
var result = string.Empty;
using (var connection = new SqlConnection(@"Database Login"))
{
await connection.OpenAsync();
var sql = "SELECT mySpecificColumn FROM table WHERE row LIKE @txt1";
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.Add("@txt1", SqlDbType.VarChar).Value = $"'{param}%'";
using (var dataReader = await command.ExecuteReaderAsync())
{
var l = new List<string>();
while (await dataReader.ReadAsync())
{
var data = dataReader.GetString(0);
l.Add(data);
}
result = string.Join(System.Environment.NewLine, l);
}
}
}
return result;
}
这将被称为:
var result = await GetDataFromRowAsync("banana");
您还需要对调用方法进行一些更改以适应该Async
模式。
如果您有任何问题或有任何疑问,请告诉我。