ASP.NET - 实现搜索功能和SQL

时间:2013-06-21 17:20:22

标签: c# asp.net sql forms search

我创建了一个表单,用户可以使用该表单来搜索事务。这是一张表格的图片:

enter image description here

现在,总价下拉列表中包含以下成员:

  1. 任何价格
  2. 确切金额
  3. 金额以下
  4. 以上金额
  5. 货币下拉列表包含成员:​​

    1. 任何货币
    2. EUR
    3. USD
    4. GBP
    5. 交易日期下拉列表包含成员:​​

      1. 任何日期
      2. 确切日期
      3. 低于日期
      4. 以上日期
      5. 交易状态下拉列表包含成员:​​

        1. 任何状态
        2. 有效
        3. 过期
        4. 付费
        5. 所有详情均来自名为付款的表格。

          有人可以帮助我如何在Payments表中搜索?我可以使用一个SQL语句来满足所有不同的可能性吗?或者我必须使用多个SQL语句?有人可以给我一个可以用来满足不同可能性的SQL语句模板吗?请帮助,因为SQL不是我最强的观点。谢谢:))

3 个答案:

答案 0 :(得分:3)

最佳解决方案是根据搜索表单中输入的字段,在C#代码中动态组装SQL查询字符串。

答案 1 :(得分:1)

更新:以下修改后的代码允许范围(包括无限范围)

如果我理解正确的话,存储过程可以轻松处理这样的查询。您只需检查NULL即可使参数可选。如果参数为NULL,请不要根据它进行查询。

CREATE PROCEDURE schema.FindPayments
(
    @MinPrice double = NULL,
    @MaxPrice double = NULL,
    @Currency char(3) = NULL,
    @MinTranDate datetime = NULL,
    @MaxTranDate datetime = NULL,
    @TranStatus int = NULL
)
AS BEGIN

    SELECT      *
    FROM        Payments
    WHERE       (
                        @MinPrice IS NULL
                    OR  TotalPrice >= @MinPrice
                )
            OR  (
                        @MaxPrice IS NULL
                    OR  TotalPrice <= @MaxPrice
                )
            OR  (
                        @Currency IS NULL
                    OR  Currency = @Currency
                )
            OR  (
                        @MinTranDate IS NULL
                    OR  TranDate >= @MinTranDate
                )
            OR  (
                        @MaxTranDate IS NULL
                    OR  TranDate <= @MaxTranDate
                )
            OR  (
                        @TranStatus IS NULL
                    OR  TranStatus = @TranStatus
                )
END

您现在可以从传递DBNull.Value的代码中为未指定的参数调用此存储过程,或者因为我已将NULL指定为所有参数的默认值,您只需传递所选参数即可。

SqlCommand l_findPayments = new SqlCommand("FindPayments", new SqlConnection("..."));
l_findPayments.CommandType = CommandType.StoredProcedure;

if ( l_totalPriceComparison == "Exact Amount" )
{
    findPayments.Parameters.Add(new SqlParameter("@MinPrice", l_price));
    findPayments.Parameters.Add(new SqlParameter("@MaxPrice", l_price));
}
else if ( l_totalPriceComparison == "Below Amount" )
    findPayments.Parameters.Add(new SqlParameter("@MaxPrice", l_price));
else if ( l_totalPriceComparison == "Above Amount" )
    findPayments.Parameters.Add(new SqlParameter("@MinPrice", l_price));
// "Any Price" will just leave the parameter
// blank, so it will not filter on price

// ... repeat for all params

SqlDataReader l_result = l_findPayments.ExecuteReader();

答案 2 :(得分:0)

一个好方法是使用您的数据库列名作为文本框/下拉列表ID。这样,您可以从后面的代码中利用它们的ID属性,您可以使用循环根据您的需要构建查询。假设您在HTML表或其他可以类似循环的结构中构建了这些内容......

string sql = "SELECT * FROM payments ";
string field = "";
string value = "";
int parameter_count = 0;
foreach(HtmlTableRow row in table.Rows)
{ 
    foreach(Control c in row.Cells[1].Controls)
    {
        if (c is Textbox)
        {
             TextBox txt = c as TextBox;
             if (txt.Text.Length > 0)
             {
                 field = txt.ID;
                 value = txt.Text.Trim();
                 if (parameter_count == 0)
                 {
                     sql += string.Format(" WHERE {0}='{1}' ", field, value);
                     parameter_count++;
                 }
                 else
                 {
                     sql += string.Format(" AND {0}='{1}' ", field, value);
                     parameter_count++;
                 }
             }
        }
        else if (c is DropDownList)
        {
            DropDownList ddl = c as DropDownList;
             if (ddl.SelectedValue.Length > 0)
             {
                 field = ddl.ID;
                 value = ddl.SelectedValue.Trim();
                 if (parameter_count == 0)
                 {
                     sql += string.Format(" WHERE {0}='{1}' ", field, value);
                     parameter_count++;
                 }
                 else
                 {
                     sql += string.Format(" AND {0}='{1}' ", field, value);
                     parameter_count++;
                  }
              }
          }
      }
  }

现在,简单地使用string.Format构建查询有一个明显的缺点,主要是您可以使用SQL注入。但是,我建议抛弃string.Format部分,因为它们纯粹是出于示例的缘故,因此您可以看到可以捕获构建正确参数化查询所需的字段/值的时刻。更重要的部分是包含这些陈述的所有逻辑。它使您能够排除空白字段,并使它们不影响查询结果,除非它们具有值。希望这有帮助!