2

我在我的 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 语句中的第一个表没有“位置”。我不知道如何使用不同的“foreach”循环为每个表实现“where”。有什么建议么?

4

1 回答 1

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 注入攻击。除非您已经事先手动清理输入,否则您应该考虑保护自己

[[一个女人在打电话,拿着杯子]] 电话:你好,这是你儿子的学校。 我们遇到了一些电脑问题。 妈妈:哦,天哪——他有没有弄坏什么东西? 电话:在某种程度上—— 电话:你真的给你儿子起过名字吗

于 2013-10-09T17:14:27.937 回答