使用SQL返回符合多个搜索条件的表行

时间:2013-06-26 13:31:22

标签: asp.net mysql .net sql

我正在尝试使用SQL,ASP.NET和查询字符串参数执行一些简单的表过滤。 我已经设置了我的项目,以便有一个带有“搜索”文本字段和“价格”文本字段的表单,并在提交表单时更新查询字符串参数,如下所示:

mydomain.com?search=test&price=100

SQL语句应返回符合搜索条件的行,但如果一行为空,则另一行仍应返回数据。目前,当'search'和'price'都有效时,会返回正确的行,但如果其中一行为空,则不返回任何内容。

这是我的代码段:

var search = Request["search"].IsEmpty() ? "" : Request["search"];
var price = Request["price"].IsEmpty() ? "" : Request["price"];

string sql = "SELECT * FROM Items WHERE ('%" + search + "%' is null OR item_name LIKE '%" + search + "%') AND ('%" + price + "%' is null OR item_price < " + price + ")";

我的理解是,如果'value is null'语句为真,那么()中的整个'AND'语句被设置为null因此被忽略。如果为false,则运行'OR ..'语句。

为什么SQL语句不能按预期的方式工作?

2 个答案:

答案 0 :(得分:4)

我找到了一个有趣的小解决方案。这有点像hackish,但它确实有效:

var sql = "SELECT * FROM table WHERE 1 == 1";
var search = "blahdiblah";
if search is not "" {
    sql += " AND item LIKE '%"+search+"%'";
}

只需根据您的代码进行调整。

所以最初你说“给我一切”,然后根据你是否有价值,你开始用AND和OR来削减所要求的数据。

为了上帝的爱,请抓住你的内联SQL!我没有在评论中开玩笑。如果我的语法正确,如果有人在您的搜索文本框中输入');DROP TABLE Items;--,它将丢弃您的整个表格。该行将关闭报价,结束声明,删除表格,并对其余部分进行评论。生成的行看起来像这样:

SELECT * FROM Items WHERE ('%');DROP TABLE Items;--%' is null OR item_name LIKE '%" + search + "%') AND ('%" + price + "%' is null OR item_price < " + price + ")
事实上,这是一张掉线表。第一个语句可能会出错,然后第二个语句将执行,其余语句将被注释掉并且不会被执行。

答案 1 :(得分:2)

除了您接触SQL注入之外,以下是Request["search"].IsEmpty()

时查询的内容
SELECT * FROM Items WHERE '%%' is null (...) ;

字符串'%%'不为空(它是一个双字符的字符串)。

相反,你想要这样的东西:

string sql = "SELECT * FROM Items WHERE '" + search + "' = '' (...)" ;

以便sql成为:

SELECT * FROM Items WHERE '' = '' (...)

或者您可以完全放弃测试'' = '',因为'%%'实际上是LIKE任何字符串:

string sql = "SELECT * FROM Items WHERE '%" + search + "%' LIKE item_name";

如果Request["search"].IsEmpty(),则您的查询如下所示:

SELECT * FROM Items WHERE '%%' LIKE item_name (...) -- always true

以上内容仅用于教育目的,因为它会产生次优查询。正确的方法是动态构建查询:

string sql = "SELECT * FROM Items WHERE";
if (!Request["search"].IsEmpty()) {
    sql += "item_name LIKE '%" + search + "%' AND";
} // else no condition on "item_name"
if (!Request["price"].IsEmpty()) {
    sql += "price < " + price ;
} // and so on

这只是概念证明。还需要进行一些调整。