0

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

mydomain.com?search=test&price=100

SQL 语句应返回满足搜索条件的行,但如果其中一个为空,则另一个应仍带回数据。目前,当“搜索”和“价格”都有效时,返回正确的行,但如果其中一个为空,则不返回任何内容。

这是我的代码片段:

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,因此将被忽略。如果它为假,则运行“OR..”语句。

为什么 SQL 语句没有按应有的方式工作?

4

2 回答 2

4

我找到了一个有趣的小解决方案。这有点骇人听闻,但它有效:

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 + ")

实际上,这是一个丢弃的表。第一条语句可能会出错,然后执行第二条语句,其余的被注释掉,不会被执行。

于 2013-06-26T13:52:27.740 回答
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

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

于 2013-06-26T13:43:02.107 回答