我正在编写一个查询,允许用户在asp.net,C#和mssql中搜索他们提供的关键字:
string projectPart = null;
string categoryPart = null;
string descriptionPart = null;
if (this.Textbox_ProjectNr.Text.Trim().Length > 0)
projectPart = " AND Number='" + this.Textbox_ProjectNr.Text.Trim() + "' ";
if (this.Textbox_Category.Text.Trim().Length > 0)
categoryPart = " AND Category LIKE '%" + this.Textbox_Category.Text.Trim() + "%' ";
if (this.Textbox_pDescription.Text.Trim().Length > 0)
descriptionPart = " AND ProductDescription LIKE '%" + this.Textbox_pDescription.Text.Trim() + "%' ";
string query = "SELECT * from Project = p.ID " + projectPart + descriptionPart + categoryPart;
我不知道这个查询是否足以进行传统的查询搜索。因为我看到这个搜索存在一些瓶颈:
我基本上不知道如何改进搜索查询。任何建议表示赞赏。
谢谢你。
答案 0 :(得分:3)
最重要的改进是保护您的代码免受SQL注入攻击。
您不应该在SQL字符串中连接原始输入。如果有人搜索以下文本,例如:
Bwah ha ha'; DROP DATABASE northwind; PRINT'
这将添加到您的查询中以生成
SELECT *
FROM mytable
WHERE category LIKE '%Bwah ha ha'; DROP DATABASE northwind; PRINT'%'
这是一个有效的SQL命令,很乐意执行和删除数据库(或执行攻击者想要的任何其他操作)
有关详细信息,请参阅SQL Injection和Santitizng Inputs。
答案 1 :(得分:1)
您必须使此查询注入证明!不要连接用户输入的值,而是使用参数,如下所示:
SqlCommand cmd = new SqlCommand(@"
SELECT * from Project
WHERE
( Number = @Number OR @Number IS NULL ) AND
( Category LIKE @Category OR @Category IS NULL ) AND
( ProductDescription LIKE @ProductDescription OR @ProductDescription IS NULL )", conn);
if(!String.IsNullOrEmpty(this.Textbox_ProjectNr.Text.Trim()))
cmd.Parameters.AddWithValue("@Number", this.Textbox_ProjectNr.Text.Trim());
if(!String.IsNullOrEmpty(this.Textbox_Category.Text.Trim()))
cmd.Parameters.AddWithValue("@Category", this.Textbox_Category.Text.Trim());
if(!String.IsNullOrEmpty(this.Textbox_pDescription.Text.Trim()))
cmd.Parameters.AddWithValue("@ProductDescription", this.Textbox_pDescription.Text.Trim());
此外,您可以在用户输入的值上添加一些客户端验证。例如,在运行该查询之前要求超过三个(?)字符。
<asp:TextBox ID="Textbox_ProjectNr" runat="server" />
<asp:RegularExpressionValidator ID="Textbox_ProjectNr_Validator" runat="server"
ControlToValidate="Textbox_ProjectNr"
ErrorMessage="Minimum length is 3"
ValidationExpression=".{3,}" />
答案 2 :(得分:0)
首先,你必须保护自己免受sql注射。您尚未指定与正在使用的数据库的连接,但大多数库允许在不同的字段中添加参数,因此它们会自动清理。
其次,您可以(并且应该)使用“LIMIT”(对于mysql)或“TOP X”限制结果计数,如下所示:
Select * from TableName LIMIT 100
或Select TOP 100 * from TableName