[英]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: 现在, 总价格下拉列表中包含以下成员:
The currency drop down list has the members: 货币下拉列表包含以下成员:
The transaction date drop down list has the members: 交易日期下拉列表包含以下成员:
The transaction status drop down list has the members: 事务状态下拉列表包含以下成员:
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.