【问题标题】:Use * as a wildcard when filtering data过滤数据时使用 * 作为通配符
【发布时间】:2015-05-18 18:48:36
【问题描述】:

我希望在 C# 中的 access 数据库中对多个列执行搜索。 数据按行构建,每列包含相关数据或“*”作为通配符。

举个粗略的例子:

如果我的数据是(,表示新单元格) 福特,嘉年华,*,1998 那么如果我有一个价值......

福特,嘉年华,汽油,1998 年

它会找到并显示该行数据。

目前我正在尝试:

string sql = "SELECT * FROM [mydatabase]  
WHERE Manufacturer ='" + textBox1.Text +  
"' OR Manufacturer='*' AND Model ='" + textBox2.Text +  
"' OR Model='*' AND Fuel ='" + textBox3.Text +  
"' OR Fuel='*' AND Year='" + textBox4.Text + "' OR Year='*'";

但这会带来所有值,而不是过滤掉它们。有没有办法在查询中使用 and if/else 而不是 OR?

【问题讨论】:

  • 您可以在 linq query 中包含 if else 语句
  • 如果你混合使用ANDOR你应该加上括号,否则AND优先于OR
  • 旁注 - 你的方法充满了 sql 注入漏洞。使用prepared statements
  • 看起来* 是数据库已经支持的null 数据库概念的自定义实现。

标签: c# sql


【解决方案1】:

如果你想使用通配符,我会从 where 子句中排除它。

或者,如果您想将所有列作为一个字符串进行搜索,您可以将它们全部添加到选择列表中的新列中。

例如:

        public void GetCars(string manufacturer, string model, string fuel, DateTime? year, string searchString)
        {
            string query = @"
                           SELECT *,
                           ISNULL([Manufacturer],'') + ' ' + ISNULL([Model],'') + ' ' ISNULL([Fuel],'') + ' ' ISNULL('Year', '') AS [SearchString]
                           FROM [MyDatabase]
                           WHERE [Manufacturer]=@Manufacturer ";

            if (!String.IsNullOrEmpty(model))
                query += @"AND [Model]=@Model ";

            if (!String.IsNullOrEmpty(fuel))
                query += "AND [Fuel]=@Fuel ";

            if (year.HasValue)
                query += "AND [Year]=@Year ";

            if (!String.IsNullOrEmpty(searchString))
                query += @"AND [SearchString] Like '%@SearchString%' ";

            using (SqlCommand sqlCommand = new SqlCommand(query))
            {
                sqlCommand.Parameters.AddWithValue("@Manufacturer", manufacturer);

                if (!String.IsNullOrEmpty(model))
                    sqlCommand.Parameters.AddWithValue("@Model", model);

                if (!String.IsNullOrEmpty(fuel))
                    sqlCommand.Parameters.AddWithValue("@Fuel", fuel);

                if (year.HasValue)
                    sqlCommand.Parameters.AddWithValue("@Year", year.Value);

                if (!String.IsNullOrEmpty(searchString))
                    sqlCommand.Parameters.AddWithValue("@SearchString", searchString);

                //Execute to data table etc
            }
        }

【讨论】:

    【解决方案2】:

    你可以使用coalesce,而不是Manufacturer ='" + textBox1.Text + "' OR Manufacturer='*',它有点像if/else

    string sql = "... Manufacturer = coalesce('" + textBox1.Text + "', '*') ...";
    

    这样,你只需要ands,而不是与or混合。这可能是现在的问题,因为 ors 导致 and 不被评估。

    您还可以在and 周围添加括号,因此or 将仅应用于括号内:

     string sql = "... where (Manufacturer ='" + textBox1.Text + "' OR Manufacturer='*') and ...";
    

    注意你应该使用parameterized queries,所以你会得到这样的东西:

    command.CommandText = "select * from ... where Manufacturer = coalesce(@mgr, '*') and ...";
    command.Parameters.Add(new SqlParameter("mgr", textBox1.Text));
    

    【讨论】:

    • 感谢您的帮助,我刚刚尝试了合并代码,但出现错误“IErrorInfo.GetDescription failed with E_FAIL(0x80004005)”。有什么想法可能导致这种情况吗?
    • 我的错,Access 不支持coalesce。你可以试试nz 代替coalesce 吗?
    猜你喜欢
    • 2021-11-12
    • 2015-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-28
    • 2021-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多