【问题标题】:Dynamically extend SQL statement - page search动态扩展 SQL 语句 - 页面搜索
【发布时间】:2010-09-09 16:00:21
【问题描述】:

在我的模型中,我有一个字符串 txtSearche,其值来自如下文本框:

“大家好”

如何编写我的语句动态添加WHERE text LIKE '%Text%' 为每个单词附加?大概是 3 次:

WHERE Text LIKE '%@Text%'";

这是我的代码:

string[] wordsFromTxtSearche = txtSearche.Split(' ');

SqlCommand cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = @"SELECT * "
                  + " FROM ForumThread "
                  + " WHERE Text LIKE '%@Text%'";
cmd.Parameters.Add(new SqlParameter("@Text", txtSearche));

我想我需要在 For 循环的帮助下完成,但我不知道怎么做。请帮帮我

【问题讨论】:

    标签: c# asp.net-mvc sql


    【解决方案1】:

    SQL不会在字符串中插入参数,你可以使用linq来清理一些乱七八糟的循环代码。

    string[] words = txtSearche.Split(' ', StringSplitOption.RemoveEmptyEntries);
    string[] paramNames = Enumerable.Range(1, words.Length)
        .Select(i => "p" + i)
        .ToArray();
    string likeClause = string.Join("AND ",
         paramNames.Select(name => "col like '%' + " + name + " + '%'");
    SqlParmeter[] sqlParams = Enumerable.Range(1, words.Length)
        .Select(i => new SqlParameter(paramNames[i], words[i]))
        .ToArray();
    
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = connection;
    cmd.CommandType = System.Data.CommandType.Text;
    cmd.CommandText = @"SELECT * FROM ForumThread WHERE " + likeClause;
    cmd.Parameters.AddRange(sqlParams);
    

    不管怎样,不要使用like 来实现论坛搜索,而是使用full text search。

    【讨论】:

      【解决方案2】:

      看看这是否有效...完全未经测试:)

      SqlCommand cmd = new SqlCommand(); 
      cmd.Connection = connection; 
      cmd.CommandType = System.Data.CommandType.Text; 
      string sql = "SELECT * FROM ForumThread WHERE ";
      // assuming you have at least 1 item always in wordsFromTxtSearche
      int count = 1;
      foreach (string word in wordsFromTxtSearche)
      {
          if (count > 1) sql += " AND ";
          sql += "Text LIKE @Text" + count.ToString();
          cmd.Parameters.Add(new SqlParameter("@Text" + count.ToString(),
              string.Format("%{0}%", word)));
          count++;
      }
      cmd.CommandText = sql;
      

      【讨论】:

      • 这里没有别的了吗??你能用“{}”写同样的吗:if (count > 1) sql += " AND "; sql += "Text LIKE @Text" + count.ToString(); cmd.Parameters.Add(new SqlParameter("@Text" + count.ToString(), string.Format("%{0}%", word)));计数++;
      【解决方案3】:

      类似:

      string command = @"SELECT * FROM ForumThread where ";
      bool first = false;
      
      foreach (string word in words)
      {
         if (first)
             command += " and ";
         else
             first = true;
      
         command += " Text like '%" + word + "%' ";
      }
      
      cmd.CommandText = command;
      

      如果你想坚持参数,你必须创建一个方案来生成一个独特的参数,可能是这样的:

      string command = @"SELECT * FROM ForumThread where ";
      bool first = false;
      
      for(int i = 0, len = words.Length; i < len; i++)
      {
         string word = words[i];
         if (first)
             command += " and ";
         else
             first = true;
      
         command += " Text like @param" + i.ToString() + " ";
         cmd.Parameters.Add("@param" + i.ToString(), "%" + words[i] + "%");
      }
      
      cmd.CommandText = command;
      

      HTH。

      【讨论】:

      • 参数化版本肯定更好。您的第一个版本吸引了 SQL 注入。
      猜你喜欢
      • 1970-01-01
      • 2018-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-19
      • 1970-01-01
      相关资源
      最近更新 更多