创建一个足够的查询搜索sql

时间:2011-11-18 09:49:10

标签: asp.net sql

我正在编写一个查询,允许用户在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;

我不知道这个查询是否足以进行传统的查询搜索。因为我看到这个搜索存在一些瓶颈:

  1. 如果用户没有输入任何内容,则返回所有数据=>为此,我只在填写其中一个字段时进行查询。
  2. 如果用户为每个字段提供一些关键字“P”,则结果将是数百万个数据。
  3. 我基本上不知道如何改进搜索查询。任何建议表示赞赏。

    谢谢你。

3 个答案:

答案 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 InjectionSantitizng 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 100Select TOP 100 * from TableName