【问题标题】:C# database search (how to create query string)C# 数据库搜索(如何创建查询字符串)
【发布时间】:2015-05-27 10:52:39
【问题描述】:

我正在尝试在我的 C# WindowsForms 应用程序中进行 MySQL 数据库搜索。我有 16 个搜索值(例如:年龄、状态、身高、体重等)。问题是,我不需要填写所有值来执行搜索,而且我不知道如何设置查询字符串。如果我只填写“年龄”和“状态”字段它应该看起来像:

 string querySearch = " SELECT * FROM table WHERE age=" + value1 +"status="+value2;
 MySqlCommand cmdSearch = new MySqlCommand(querySearch, conn);
 readerSearch = cmdSearch.ExecuteReader();
 readerSearch.Read(); 

但我不知道用户要填写多少个字段,所以我必须更动态地编写查询(WHERE 部分)。谁能建议如何解决这个问题?谢谢。

【问题讨论】:

  • 你不应该将输入连接到 SQL 中;如果可能总是使用参数 - 上面的 SQL 注入看起来已经成熟了

标签: c# mysql database search


【解决方案1】:

我曾经在一个程序中遇到过类似的事情,我的做法是这样的:

//viewselected is list of strings
//combobox1 has all items from the viewselected as options

//start building the select query
        string command = "SELECT ";
        for (int i = 0; i < viewselected.Count; i++)
        {//add each selected database item
            if (i == viewselected.Count - 1)
            {//if it's the last item in the list don't add a comma
                command = command + viewselected[i];
                Console.WriteLine("Showing " + AcessStuff.viewselected[i]);
            }
            else
            {
                command = command + viewselected[i] + ",";
                Console.WriteLine("Showing " + AcessStuff.viewselected[i]);
            }
        }//add last pice of query command - the combobox has all the columns that are
         // in the list added so the user can select a column to sort it on
        command = command + " FROM ART ORDER BY " + comboBox1.Text.ToString() + "";

然后您就可以使用字符串“command”作为 sql 命令字符串。只要您确保验证列表中至少有 1 个项目,它应该可以正常工作。

注意:这一行占用了所有行,而不是任何特定行,而是使用

command = command + viewselected[i] + ",";

你可以使用类似的东西

command = command + viewselected[i] + "=@" + viewselected[i] + ",";

但是,这确实希望您有一个与数据库列同名的变量(示例列“ID”将具有变量“@ID”。

【讨论】:

    【解决方案2】:

    我更喜欢这种方法。我讨厌在应用程序中构建 SQL 查询

    select * from [Table] where (filter1 is not null and Column1 = filter1) or     (filter2 is not null and Column2 = filter2) or (filter3 is not null and Column3 LIKE '%' + filter3) .. or ()
    

    【讨论】:

      【解决方案3】:

      您可以尝试从一个基本的查询字符串开始,并在 StringBuilder 中保留要添加的条件。如果您找到要添加的条件,则在 stringbuilder 中插入条件并在列表中添加匹配的参数。在检查结束时,您可以根据需要轻松添加 WHERE 条件并将参数添加到命令中

      List<MySqlParameter> prms = new List<MySqlParameter>();
      StringBuilder sb = new StringBuilder();
      string query = "SELECT * FROM table";
      
      if(txtBoxStatus.Text.Trim().Length > 0)
      {
         sb.Append(" status = @status AND ");
         prms.Add("@status", MySqlDbType.VarChar).Value = txtBoxStatus.Text.Trim();
      }
      if(txtBoxAge.Text.Trim().Length > 0)
      {
         int age;
         if(Int32.TryParse(txtBoxAge.Text, out age))
         {
             sb.Append(" age = @age AND ");
             prms.Add("@age", MySqlDbType.Int).Value = age;
         }
      }
      .... so on for other parameters
      ....
      .... and at the end 
      MySqlCommand cmdSearch = new MySqlCommand(query + sb.ToString(), conn);
      if(sb.Length > 0)
      {
          // If you enter here you have one or more WHERE conditions 
          // AND a list of parameters to add to the query
          sb.Insert(0, " WHERE ");
          sb.Length -= 5; // remove the last ' AND '
          cmdSearch.Parameters.AddRange(prms.ToArray());
      }
      readerSearch = cmdSearch.ExecuteReader();
      ....
      

      您应该始终使用参数化查询而不是字符串连接,因为这会导致Sql Injection

      【讨论】:

        【解决方案4】:

        要遵循最佳实践等,您应该使用参数;像这样的东西应该可以工作:

        bool first = true;
        var sb = new StringBuilder("SELECT * FROM table");
        if(age != null) { // or >= 0, or whatever
            sb.Append(first ? " WHERE " : " AND ").Append("age=@age");
            first = false;
            cmd.Parameters.AddWithValue("@age", age);
        }
        if(status != null) { // or != "", or whatever
            sb.Append(first ? " WHERE " : " AND ").Append("status=@status");
            first = false;
            cmd.Parameters.AddWithValue("@status", status);
        }
        cmd.CommandText = sb.ToString();
        using(var reader = cmd.ExecuteReader()) {
            // etc
        } 
        

        【讨论】:

          【解决方案5】:

          我认为这可能会有所帮助:

          1. 创建一个 bulid_where 方法

            private string build_where(string where, string clause)
            {
                if (clause == "")
                {
                    return where;
                }
            
                string sql;
            
                if (where == "")
                {
                    sql = " where ";
                    sql += clause;
                }
                else
                {
                    sql = where;
                    sql += "and ";
                    sql += clause;
                }
            
                return sql;
            }
            
          2. 构建sql语句时调用方法

                 string where = "";
            
            
                where = build_where(where, age);
                where = build_where(where, status); 
            

            ...

          【讨论】:

            【解决方案6】:

            这样的事情怎么样:

            string querySearch = " SELECT * FROM table "
            addConditionToQuery(querySearch, "age", textboxAge.text);
            addConditionToQuery(querySearch, "status", textboxStatus.text);
            ...
            
            void addConditionToQuery(string Query, string ColumnName, string Value) {
                if(!String.IsNullOrWhiteSpace(Value)) {
                  if(Query.IndexOf("WHERE")>-1) {
                    Query += "WHERE ";
                  } else {
                    Query += "AND ";
                  }
                    Query += ColumnName +" = '" + Value + "' ";
                }
            }
            

            注意:这只是一个例子。您将需要实现一种稍微不同的方法来比较不同的 sql 数据类型(例如整数)。

            【讨论】:

              【解决方案7】:

              我经常使用的一个技巧是用一个简单的条件结束查询字符串,然后根据需要添加字段。例如

              // Note the trivial condition
              string query = "SELECT * FROM table WHERE 1 = 1";
              
              // Add any number of "AND ..." clauses, as needed.
              if( age.HasValue ) query += " AND age = " + age.Value;
              if( name.HasValue) query += " AND name LIKE \"%" + name.Value + "\"";
              if( id.HasValue) query += " AND id = " + id.value;
              // ...
              
              MySqlCommand cmdSearch = new MySqlCommand(querySearch, conn);
              readerSearch = cmdSearch.ExecuteReader();
              readerSearch.Read(); 
              

              请注意,这是一个非常简单的示例,仅用于说明“WHERE 1 = 1”技巧。实际上您应该始终使用查询参数,或者至少验证您的用户输入。 字符串连接也可以替换为StringBuilder 以获得更好的性能。

              【讨论】:

              • 啊,我的错 - 它主要从样本中跳出来
              • 没问题,你说得很好,所以我加了一些粗斜体;)
              猜你喜欢
              • 2018-02-21
              • 1970-01-01
              • 2019-02-16
              • 1970-01-01
              • 1970-01-01
              • 2016-05-10
              • 1970-01-01
              • 1970-01-01
              • 2013-12-10
              相关资源
              最近更新 更多