简体   繁体   English

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

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

I have created a form which the user can use in order to search for transactions. 我创建了一个表单,用户可以使用该表单来搜索事务。 This is a picture of the form: 这是一张表格的图片:

在此输入图像描述

Now, the total price drop down list has the members: 现在, 总价格下拉列表中包含以下成员:

  1. Any Price 任何价格
  2. Exact Amount 确切金额
  3. Below Amount 低于金额
  4. Above Amount 超过金额

The currency drop down list has the members: 货币下拉列表包含以下成员:

  1. Any Currency 任何货币
  2. EUR 欧元
  3. USD 美元
  4. GBP 英镑

The transaction date drop down list has the members: 交易日期下拉列表包含以下成员:

  1. Any Date 任何日期
  2. Exact Date 准确日期
  3. Below Date 低于日期
  4. Above Date 以上日期

The transaction status drop down list has the members: 事务状态下拉列表包含以下成员:

  1. Any Status 任何状态
  2. Active 活性
  3. Expired 过期
  4. Paid 付费

All the details are being fetched from a table called Payments . 所有细节都来自名为Payments的表格。

Can someone please help me how I can go about to search in the Payments table? 有人可以帮助我如何在Payments表中搜索? Can I satisfy all the different possibilities using one SQL statement? 我可以使用一个SQL语句来满足所有不同的可能性吗? Or do I have to use multiple SQL statements? 或者我必须使用多个SQL语句? Can someone please give me a template of an SQL statement that can be used to satisfy the different possibilities? 有人可以给我一个可以用来满足不同可能性的SQL语句模板吗? Please help since SQL is not my strongest point. 请帮助,因为SQL不是我最强的观点。 Thank you :) 谢谢 :)

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

UPDATE: Modified code below to allow ranges (including unbounded ranges) 更新:修改下面的代码以允许范围(包括无界范围)

A stored proc can easily handle queries such as this, if I understand correctly. 如果我理解正确,存储过程可以轻松处理这样的查询。 You can make the parameters optional simply by checking for NULL . 您可以通过检查NULL来使参数可选。 If a parameter is NULL , don't query based on it. 如果参数为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

You can now call this stored proc from code passing in either DBNull.Value for unspecified parameters or, because I've assigned NULL as the default for all paramters, you can just pass the selected parameters. 您现在可以从传递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();

A good way to do it is to use your DB column names as the text box/dropdown id's. 一个好方法是使用数据库列名作为文本框/下拉列表ID。 that way, you can utilize their ID property from the code behind and you can use a loop to build a query based on your needs. 这样,您可以从后面的代码中利用它们的ID属性,您可以使用循环根据您的需要构建查询。 Assuming that you have these build in an HTML table or some other structure that can be similarly looped... 假设您在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++;
                  }
              }
          }
      }
  }

Now, there is an obvious drawback to simply using the string.Format to build your query, mainly that you are open to SQL injections. 现在,简单地使用string.Format来构建查询有一个明显的缺点,主要是您可以使用SQL注入。 However, I would suggest throwing out the string.Format section as they were purely for the sake of the example so that you could see the moment where you can capture the fields/values you will need to build a properly parameterized query. 但是,我建议抛弃string.Format部分,因为它们纯粹是出于示例的缘故,因此您可以看到可以捕获构建正确参数化查询所需的字段/值的时刻。 The more important piece of this is all of the logic that wraps around those statements. 更重要的部分是包含这些陈述的所有逻辑。 It gives you the ability to exclude the blank fields, and make them not affect the query result unless they have a value. 它使您能够排除空白字段,并使它们不影响查询结果,除非它们具有值。 Hope this helps! 希望这可以帮助!

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

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