我有一个.aspx页面,其中的产品在SQL Server 2005数据库中分为不同的类别。
用户应该能够从任何组合中进行选择。例如,从COLOR类别中选择“Beige”和“Black”,从STYLES类别中选择“Tapestry”,只能选择带有Beige + Tapestry和Black + Tapestry的产品。
我正在考虑使用WHERE子句来检查: 如果检查了任何COLOR复选框,则使用WhereCluaseColor + =复选框值,将这些复选框的值构建到'WhereClauseColor'字符串变量中;
如果检查了任何STYLES复选框,则使用另一个名为WhereClauseStyles的变量 - 就像在Color类别中一样。
最后,构建一个名为WhereClause的sql字符串: 如果WhereClauseColor!=“”则WhereClause + = AND''''字段在db中包含WhereClauseColor;
对于样式来说类似的东西。但我没有运气。可能我需要一种完全不同的方法。太糟糕了,客户希望产品成为复选框,以允许在每个类别下进行多项选择。
WhereClause = "SELECT * FROM [xxxx] WHERE 0 = 1";
/////COLORS
// if (Request.Form["color_gold"] != null) { WhereClause += " OR xxx.color = 'gold'"; }//// OLD CODE. . 08/04/11
if (Request.Form["color_spice"] != null) { WhereClause += " OR CONTAINS (xxxx.color,'spice')"; }/// ## NEW CODE: NOTE CONTAINS. . 08/04/11
答案 0 :(得分:0)
您是否曾尝试在SSMS中构建所需的SQL选择查询以获得正确的语法,以便在您开始构建动态查询时至少现在您的目标是什么?这就是我要这样做的方式。
您也可以在SQL中使用临时表执行所有操作,其中第一个查询采用第一个选中的复选框(作为params传递给存储过程,并在下一节中处理下一组复选框)你的存储过程。
答案 1 :(得分:0)
我不确切知道您使用Request.Form
的原因。像if (chkSpice.Checked)
这样的东西会更具可读性。
如果您必须将SQL保留在代码中,并且不能使用存储过程,那么这是您可以执行此操作的一种方法。您不接受用户输入并在SQL中传递它,因此没有SQL注入风险。
如果您知道在数据库中命名的样式和颜色,SQL IN
运算符会更有效。
string styles = String.Empty;
string colors = String.Empty;
if (chkTapestry.Checked)
styles = "'Tapestry'";
else if (chkRug.Checked)
styles += ",'Rug'";
if (chkBlack.Checked)
colors = "'Black'";
else if (chkBeige.Checked)
colors += ",'Beige'";
string sql = "SELECT * FROM [X]";
if (styles.Length > 0 && colors.Length > 0)
sql += String.Format(" WHERE [Style] IN ({0}) AND [Color] IN ({1})", styles, colors);
else if (styles.Length > 0)
sql += String.Format(" WHERE [Style] IN ({0})", styles);
else if (colors.Length > 0)
sql += String.Format(" WHERE [Color] IN ({0})", colors);
以上是一种相当手动的方法来组合样式和颜色,并使用令人遗憾的样式和颜色名称的硬编码。更好的设计可能是:
然后,在PostBack上:
Color IN (...)
部分中使用的颜色列表中。这可确保您使用数据库中的值,而不是可能被用户篡改的值。示例代码:
protected DataTable dtColors
{
get
{
if (Session["fabrics-dtColors"] == null)
Session["fabrics-dtColors"] = FetchDataTable("SELECT DISTINCT Color FROM X ORDER BY Color");
return (DataTable)Session["fabrics-dtColors"];
}
}
protected DataTable dtStyles
{
get
{
if (Session["fabrics-dtStyles"] == null)
Session["fabrics-dtStyles"] = FetchDataTable("SELECT DISTINCT Style FROM X ORDER BY Style");
return (DataTable)Session["fabrics-dtStyles"];
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
cblColors.DataSource = dtColors;
cblColors.DataBind();
cblStyles.DataSource = dtStyles;
cblStyles.DataBind();
}
}
protected void btnSearch_OnClick(object sender, EventArgs e)
{
string colors = String.Empty;
string styles = String.Empty;
string sql = "SELECT * FROM [X]";
if (cblColors.SelectedIndex > -1)
{
for (int i = 0; i < cblColors.Items.Count; i++)
{
if (cblColors.Items[i].Selected)
{
colors += String.Format("'{0}',", dtColors.Rows[i][0]);
}
}
colors = colors.TrimEnd(',');
}
if (cblStyles.SelectedIndex > -1)
{
for (int i = 0; i < cblStyles.Items.Count; i++)
{
if (cblStyles.Items[i].Selected)
{
styles += String.Format("'{0}',", dtStyles.Rows[i][0]);
}
}
styles = styles.TrimEnd(',');
}
if (styles.Length > 0 && colors.Length > 0)
sql += String.Format(" WHERE [Style] IN ({0}) AND [Color] IN ({1})", styles, colors);
else if (styles.Length > 0)
sql += String.Format(" WHERE [Style] IN ({0})", styles);
else if (colors.Length > 0)
sql += String.Format(" WHERE [Color] IN ({0})", colors);
GetSearchResults(sql);
}
答案 2 :(得分:0)
private List<string> arrColors = new List<String>();
private List<string> arrStyles = new List<String>();
if (Request.Form["color_spice"] != null) {
arrColors.Add("spice"); }/// ## NEW CODE: NOTE CONTAINS. . 08/04/11
if (Request.Form["color_gold"] != null) { arrColors.Add("gold"); }
string sql = "select * from ado_products_fabrics where [color] in('";
sql += string.Join("','", this.arrColors.ToArray());
sql += "')";
sql += " AND [style] in('";
sql += string.Join("','", this.arrStyles.ToArray());
sql += "')";
WhereClause = sql;/
答案 3 :(得分:0)
我一直在研究一个名为QBuilder的库,以使这种动态sql生成更容易一些。它可能对你有用。
答案 4 :(得分:-1)
从您的各种选择中构建应用程序代码中的表:SelectedColors,Selected Styles,....然后将它们作为参数传递给在WHERE子句中使用它们的存储过程:
where ( Color in (select Color from SelectedColors) or
not exists ( select Color from SelectedColors ) ) and ...
我假设如果没有对给定类别进行选择,例如打印比例,您要接受所有值。
这将允许您进行多项选择并防止SQL注入攻击。