多选项搜索的语法

本文关键字:语法 搜索 选项 | 更新日期: 2023-09-27 18:31:30

ASP.NET 4.0, Web forms, C#, SQL

我几乎有一些类似于你在约会网站上看到的搜索表单的东西。多个下拉框,每个 ddbox 都有特定的值以及"any"值。我想不出一种简单的方法来在下面的示例之外创建此语法,并在 c# 代码隐藏按钮单击事件中使用许多其他 if 语句:

if
= && = && =
else if<br/>
= && = && !=
else if<br/>
= && != && != 
else if<br/>
!= && = && !=

。这是具有选定值
的相同序列

if
Any && Any && Any
else if
Any && Any && Not Any
else if
Any && Not Any && Not Any
else if
Not Any && Any && Not Any

这种情况一直持续到我循环浏览所有场景。单击按钮时,后面的代码将采用选定的值并决定要执行的查询。似乎引起头痛的是ddbox中的值"any"。是否有一种首选方法来构建 c# 或 sql 语法以减少 else if 的数量?

让我知道这是否有意义,或者您是否需要更多信息。

多选项搜索的语法

我会写这样的东西:

create procedure usp_search (
    @param1 varchar(50) = null
   ,@param2 carchar(50) = null
) as
begin
    select field1
          ,field2
          ,field3
          ,fieldN
      from table t with(nolock)
     where ((@param1 is null) or (t.fieldX == @param1))
       and ((@param2 is null) or (t.fieldY == @param2))
end

然后在你的客户上你喜欢

//code
var connection = new SqlConnection("connection_string");
var command = new SqlCommand();
command.Connection = connection;
command.CommandText = "usp_Search";
command.CommandType = CommandType.StoredProcedure;
if((string.IsNullOrEmpty(stringVariable1)) || (stringVariable2.ToLower().Equals("any"))) {
    command.Parameters.Add("@param1", SqlType.VarChar, 50).Value = DBNull.Value;
} else {
    command.Parameters.Add("@param1", SqlType.VarChar, 50).Value = stringVariable1;
}
if((string.IsNullOrEmpty(stringVariable2)) || (stringVariable2.ToLower().Equals("any"))) {
    command.Parameters.Add("@param2", SqlType.VarChar, 50).Value = DBNull.Value;
} else {
    command.Parameters.Add("@param2", SqlType.VarChar, 50).Value = stringVariable2;
}
// code

类似的东西...这样,您的搜索查询可以检索筛选或未筛选的结果。当然,您必须注意此类查询的一些陷阱

编辑:仅在 C# 代码中执行的相同操作如下所示:

var sb = new StringBuilder();
sb.Append("select field1 ,field2, field3, fieldN ");
sb.Append("from table t with(nolock) ");
sb.Append("where ((@param1 is null) or (t.fieldX == @param1))");
sb.Append("and ((@param2 is null) or (t.fieldY == @param2))");
var connection = new SqlConnection("connection_string");
var command = new SqlCommand();
command.Connection = connection;
command.CommandText = sb.ToString();
command.CommandType = CommandType.Text;
if((string.IsNullOrEmpty(stringVariable1)) || (stringVariable2.ToLower().Equals("any"))) {
    command.Parameters.Add("@param1", SqlType.VarChar, 50).Value = DBNull.Value;
} else {
    command.Parameters.Add("@param1", SqlType.VarChar, 50).Value = stringVariable1;
}
if((string.IsNullOrEmpty(stringVariable2)) || (stringVariable2.ToLower().Equals("any"))) {
    command.Parameters.Add("@param2", SqlType.VarChar, 50).Value = DBNull.Value;
} else {
    command.Parameters.Add("@param2", SqlType.VarChar, 50).Value = stringVariable2;
}

首先,我建议在下一个项目中考虑使用 ORM,因为动态 sql 在应用程序设计方面有很多这样的警告。

也就是说,我处理这个问题的方式是将任何可选的搜索词放在括号内,这样我就可以这样做:

(SomeField = 'Blah' OR 1=1)

请记住,我并不是说这是一个很好的解决方案,但它确实允许您减少嵌套语句的数量,因为您可以按顺序构造 SQL 语句。

请考虑以下代码:

SQL = "SELECT CompanyName, CompanyState FROM Companies WHERE ";
SQL += "(CompanyName = '" & CompanyName & "' " + (CompanyName == "AnyKey" ? " OR 1=1" : "") + ") ";
SQL += "(CompanyState = '" & CompanyState & "' " + (CompanyState == "AnyKey" ? " OR 1=1" : "") + ") ";

我再次强调,这不应该被认为是好的。从那以后,我转向了 ORM,所以我不再有这个问题了。与往常一样,请务必清理您的用户输入。

希望这有帮助。