高级数据库搜索的一个示例

时间:2010-03-24 12:05:09

标签: asp.net database vb.net search

我正在寻找一个示例脚本。我昨天看到了一个,但是对于我的生活,今天我再也找不到了。

我的任务是允许用户通过aspx页面上的输入控件搜索1个数据库表,在那里他们可以选择和/或等于组合字段,使用concat / stringbuilder或类似的方式动态生成sql。 (它在公司防火墙后面运行)

请有人指出我的示例或教程的正确方向

我一直在页面上工作,但遇到了问题。这是Page_load;

 Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim sql As String = ("Select * From Table Where ")

    'variables to hold the and or values between fields
    Dim andor1v As String = AndOr1.SelectedValue.ToString()
    Dim andor2v As String = AndOr2.SelectedValue.ToString()
    Dim andor3v As String = AndOr3.SelectedValue.ToString()
    Dim andor4v As String = AndOr4.SelectedValue.ToString()
    Dim andor5v As String = AndOr5.SelectedValue.ToString()
    Dim andor6v As String = AndOr6.SelectedValue.ToString()

    'variables to stop web control inputs going direct to sql 
    Dim name As String = NameSearch.Text.ToString()
    Dim email As String = EmailSearch.Text.ToString()
    Dim city As String = CitySearchBox.Text.ToString()
    Dim province As String = ProvinceSelect.SelectedValue.ToString()
    Dim qualifications As String = QualificationsObtained.Text.ToString()
    Dim competencies As String = CompetenciesDD.SelectedValue.ToString()
    Dim expertise As String = Expertiselist.SelectedValue.ToString()

    If NameSearch.Text IsNot String.Empty Then
        sql += "Surname LIKE '%" & name & "%' "
    End If

    If EmailSearch.Text IsNot String.Empty Then
        sql += andor1v & " Email LIKE '%" & email & "%' "
    End If

    If CitySearchBox.Text IsNot String.Empty Then
        sql += andor2v & " City LIKE '%" & city & "%' "
    End If

    If QualificationsObtained.Text IsNot String.Empty Then
        sql += andor3v & " (institutionquals1 LIKE '%" & qualifications & "%') OR " & _
        "(institutionquals2 LIKE '%" & qualifications & "%') OR " & _
        "(institutionquals3 LIKE '%" & qualifications & "%') OR " & _
        "(institutionquals4 LIKE '%" & qualifications & "%') "
    End If

    Dim selectedrow As String = CompetenciesDD.SelectedValue.ToString
    Dim selectedquals As String = NQFlevel.SelectedValue.ToString
    If CompetenciesDD.SelectedValue.ToString IsNot "0" And selectedquals = 0 Then
        sql += (selectedrow & " = 1 ")

    ElseIf selectedrow = "assessortrue" And selectedquals IsNot "0" Then
        sql += andor4v & (" assessortrue=1  and assessorlvl=" & selectedquals)
    ElseIf selectedrow = "coordinatortrue" And selectedquals IsNot "0" Then
        sql += andor4v & ("coordinatortrue=1 and coordinatorlvl=" & selectedquals)
    ElseIf selectedrow = "facilitatortrue" And selectedquals IsNot "0" Then
        sql += andor4v & ("facilitatortrue=1 and facilitatorlvl=" & selectedquals)
    ElseIf selectedrow = "moderatortrue" And selectedquals IsNot "0" Then
        sql += andor4v & ("moderatortrue=1 and moderatorlvl=" & selectedquals)
    ElseIf selectedrow = "productdevelopertrue" And selectedquals IsNot "0" Then
        sql += andor4v & ("productdevelopertrue=1 and productdeveloperlvl=" & selectedquals)
    ElseIf selectedrow = "projectmanagertrue" And selectedquals IsNot "0" Then
        sql += andor4v & ("projectmanagertrue=1 and projectmanagerlvl=" & selectedquals)
    End If

    Response.Write(sql)

End Sub

经过一个小时的修补后,代码现在正如上面的那样^

现在我面临的问题是,如果用户没有为姓氏(第一个字段)输入值,但确实为电子邮件(或任何后续字段)输入了值,则生成的sql会有额外的内容,就像这样; < / p>

Select * From Table Where And Email LIKE '%test%' 

我也在寻找一种方法来考虑OR选项。你是否认为这应该像马丁所说的那样整个查询是和/或不是2的混合?然后我应该能够取出所有和/或下降?

感谢。

注意:我不是在寻找关于如何参数化或关于sql注入的评论。

5 个答案:

答案 0 :(得分:1)

关于用户未选择选项的问题,您只需删除“请选择”并将其默认为“和”

如果选择AND和OR的混合,那么期望的行为是什么?

默认情况下,在没有任何括号

的情况下,将首先评估AND

http://msdn.microsoft.com/en-us/library/ms186992.aspx

所以,如果他们进入

  

name =“Fred”或email =“blah”和   city =“london”和省=“xyz”或   资格= “度”

我不确定所需的语义是什么?

是吗

  

(name =“Fred”或email =“blah”)和   city =“london”和(省=“xyz”或   资格= “度”)

  

(name =“Fred”或(email =“blah”and。)   city =“london”)和省=“xyz”)或   资格= “度”

还是别的什么?也许你应该将它们限制为整个查询的AND或OR,或者允许它们通过用括号键入高级搜索语法或提供查询构建器UI来消除歧义。

答案 1 :(得分:1)

为了避免sql注入并允许动态搜索,我可能会编写类似这样的存储过程。如果未选择任何内容,请将ado.net参数集合中的DBNull.Value作为参数值发送。使用此方法,您可以检查所需的任何列,如果用户未选择它们,则会忽略它们。

编辑:我刚看到你不允许使用存储过程。我在下面更改了我的答案,以显示参数化的sql语句

SELECT * FROM TABLE
WHERE ([name] = @name OR @name IS NULL)
AND (email = @email OR @email IS NULL)
AND (city = @city OR @city IS NULL)
AND (province = @province OR @province IS NULL)
AND (qualifications = @qualifications OR @qualifications IS NULL)
AND (competencies = @competencies OR @competencies IS NULL)
AND (expertise = @expertise OR @expertise IS NULL)

答案 2 :(得分:0)

用于构建查询的Concat字符串绝不是一个好主意。您应该使用存储过程或参数化查询

答案 3 :(得分:0)

我在经典asp上完成了这个“动态”类型的查询界面。

我给你的建议是你试图在一个页面加载中完成整个查询......

通过“向导”类型界面查看“构建”查询 - 新旧的ajax或查询构建的每个部分的简单多个页面。

这本质上为您提供了“持久性”,通过您对查询的每个部分具有的(会话,dbstore,cookie等),您可以在构建时检查查询的每个部分。

答案 4 :(得分:0)

 Dim sql As String = ("Select * From Table Where **1=1**")

    'variables to hold the and or values between fields
    Dim andor1v As String = AndOr1.SelectedValue.ToString()
    Dim andor2v As String = AndOr2.SelectedValue.ToString()
    Dim andor3v As String = AndOr3.SelectedValue.ToString()
    Dim andor4v As String = AndOr4.SelectedValue.ToString()
    Dim andor5v As String = AndOr5.SelectedValue.ToString()
    Dim andor6v As String = AndOr6.SelectedValue.ToString()

    'variables to stop web control inputs going direct to sql 
    Dim name As String = NameSearch.Text.ToString()
    Dim email As String = EmailSearch.Text.ToString()
    Dim city As String = CitySearchBox.Text.ToString()
    Dim province As String = ProvinceSelect.SelectedValue.ToString()
    Dim qualifications As String = QualificationsObtained.Text.ToString()
    Dim competencies As String = CompetenciesDD.SelectedValue.ToString()
    Dim expertise As String = Expertiselist.SelectedValue.ToString()

    If NameSearch.Text IsNot String.Empty And andor1v IsNot "0" Then
        sql += "**and** Surname LIKE '%" & name & "%' " 
    ElseIf NameSearch.Text IsNot String.Empty And andor1v Is "0" Then
        sql += "**or** Surname LIKE '%" & name & "%' "
    End If

  ....additional logic here.....
    Response.Write(sql)

End Sub

注意**部分。在大多数DBMS上,1 = 1的计算结果为true。这样你就可以开始连接你的or / ands而不用担心()的