简体   繁体   中英

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 .

Can someone please help me how I can go about to search in the Payments table? Can I satisfy all the different possibilities using one SQL statement? Or do I have to use multiple SQL statements? Can someone please give me a template of an SQL statement that can be used to satisfy the different possibilities? Please help since SQL is not my strongest point. 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 . If a parameter is NULL , don't query based on it.

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.

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. 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. Assuming that you have these build in an HTML table or some other structure that can be similarly looped...

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. 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. 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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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