我创建了一个表单,用户可以使用该表单来搜索事务。这是一张表格的图片:
现在,总价下拉列表中包含以下成员:
货币下拉列表包含成员:
交易日期下拉列表包含成员:
交易状态下拉列表包含成员:
所有详情均来自名为付款的表格。
有人可以帮助我如何在Payments表中搜索?我可以使用一个SQL语句来满足所有不同的可能性吗?或者我必须使用多个SQL语句?有人可以给我一个可以用来满足不同可能性的SQL语句模板吗?请帮助,因为SQL不是我最强的观点。谢谢:))
答案 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部分,因为它们纯粹是出于示例的缘故,因此您可以看到可以捕获构建正确参数化查询所需的字段/值的时刻。更重要的部分是包含这些陈述的所有逻辑。它使您能够排除空白字段,并使它们不影响查询结果,除非它们具有值。希望这有帮助!