我正在尝试使用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语句不能按预期的方式工作?
答案 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
这只是概念证明。还需要进行一些调整。