我在我的asp.net网站上实现了全文搜索,在搜索一个表时有效。但是,我希望用户能够同时搜索两个完全不同的表。我正在尝试使用以下代码:
public List<Article> Search(List<string> keywords)
{
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.Append("select [aName],[aDesc] from [Table1] union select [bName],[bDesc] from [Table2] where");
foreach (string item in keywords)
{
sqlBuilder.AppendFormat("([bName] like '%{0}%' or [bDesc] like '%{0}%') and ", item);
}
//foreach (string item in keywords)
//{
//sqlBuilder.AppendFormat("([aName] like '%{0}%' or [aDesc] like '%{0}%') and ", item);
//}
string sql = sqlBuilder.ToString(0, sqlBuilder.Length - 4);
return QueryList(sql);
}
此代码始终显示第一个表中的所有记录,并仅在第二个表上执行搜索。现在这显然是因为我在sql语句中的第一个表没有'where'。我无法弄清楚如何使用不同的'foreach'循环实现每个表的'where'。有什么建议吗?
答案 0 :(得分:2)
UNION
将加入两个不同查询的结果。在每个查询完成执行后应用联合,因此您需要两个WHERE
子句:
select [aName],[aDesc] from [Table1]
where ([aName] like '%{0}%' or [aDesc] like '%{0}%')
union
select [bName],[bDesc] from [Table2]
where ([bName] like '%{0}%' or [bDesc] like '%{0}%')
代码中最简单的实现方法是分别构建两个查询,然后将它们连接在一起:
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.Append("select [aName],[aDesc] from [Table1] where ");
foreach (string item in keywords)
{
sqlBuilder.AppendFormat(
"([aName] like '%{0}%' or [aDesc] like '%{0}%') and ", item);
}
// That last "AND" requires a boolean statement to follow
// 1=1 will always return true and thus will not affect
// the result of your WHERE clause.
sqlBuilder.Append("1 = 1 ");
sqlBuilder.Append("UNION select [bName],[bDesc] from [Table2] where ");
foreach (string item in keywords)
{
sqlBuilder.AppendFormat(
"([bName] like '%{0}%' or [bDesc] like '%{0}%') and ", item);
}
foreach
循环的替代方法:
sqlBuilder.Append("select [aName],[aDesc] from [Table1] where ");
sqlBuilder.Append(
string.Join(
" and ",
keywords.Select( k => string.Format(
"([aName] like '%{0}%' or [aDesc] like '%{0}%')", k )
.ToArray()
)
)
sqlBuilder.Append("UNION select [bName],[bDesc] from [Table2] where ");
sqlBuilder.Append(
string.Join(
" and ",
keywords.Select( k => string.Format(
"([bName] like '%{0}%' or [bDesc] like '%{0}%')", k )
.ToArray()
)
)
但请注意,这将是 非常 效率低下的查询。如果您要搜索的行数超过几百行,我 高度 建议您考虑其他方法。
此外,您似乎容易受SQL Injection attacks攻击。除非您事先已手动清理输入,否则应考虑protecting yourself。