繁体   English   中英

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

[英]ASP.NET - Implementing Search Functionality and SQL

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

在此输入图像描述

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

  1. 任何价格
  2. 确切金额
  3. 低于金额
  4. 超过金额

货币下拉列表包含以下成员:

  1. 任何货币
  2. 欧元
  3. 美元
  4. 英镑

交易日期下拉列表包含以下成员:

  1. 任何日期
  2. 准确日期
  3. 低于日期
  4. 以上日期

事务状态下拉列表包含以下成员:

  1. 任何状态
  2. 活性
  3. 过期
  4. 付费

所有细节都来自名为Payments的表格。

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

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

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

如果我理解正确,存储过程可以轻松处理这样的查询。 您可以通过检查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();

一个好方法是使用数据库列名作为文本框/下拉列表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部分,因为它们纯粹是出于示例的缘故,因此您可以看到可以捕获构建正确参数化查询所需的字段/值的时刻。 更重要的部分是包含这些陈述的所有逻辑。 它使您能够排除空白字段,并使它们不影响查询结果,除非它们具有值。 希望这可以帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM