SQL Query根据用户输入查找匹配值

时间:2009-09-10 13:27:28

标签: sql sql-server asp-classic

我正在为房地产经纪人和租户建立一个网站。租户可以注册并填写所需的物业位置,包括街道,城镇和邮政编码。一旦他们注册,这将自动通过电子邮件发送具有符合这些搜索条件的属性的代理。

目前我的查询设置如下,以便在街道,城镇或邮政编码上匹配。

<%
Dim rspropertyresults
Dim rspropertyresults_numRows

Set rspropertyresults = Server.CreateObject("ADODB.Recordset")
rspropertyresults.ActiveConnection = MM_dbconn_STRING
rspropertyresults.Source = "SELECT * FROM VWTenantPropertiesResults "

'WHERE     (ContentStreet = 'Holderness Road') OR (ContentTown = 'Hull') OR (ContentPostCode = 'HU')

rspropertyresults.Source = rspropertyresults.Source& "WHERE (ContentStreet = '" & Replace(rspropertyresults__varReqStreet, "'", "''") & "'"

rspropertyresults.Source = rspropertyresults.Source& "OR ContentTown = '" & Replace(rspropertyresults__varReqTown, "'", "''") & "' "
rspropertyresults.Source = rspropertyresults.Source& "OR ContentTrimmedPostCode = '" & Replace(varPostcode, "'", "''") & "' ) "

rspropertyresults.Source = rspropertyresults.Source& "AND (( ContentBedRooms >= " & Replace(rspropertyresults__varBedroomsNoMin, "'", "''") & " "
rspropertyresults.Source = rspropertyresults.Source& "AND ContentBedRooms <= " & Replace(rspropertyresults__varBedroomsNoMax, "'", "''") & " ) "

rspropertyresults.Source = rspropertyresults.Source& "AND ( ContentPrice > = " & Replace(rspropertyresults__varPriceMin, "'", "''") & " "
rspropertyresults.Source = rspropertyresults.Source& "AND ContentPrice <= " & Replace(rspropertyresults__varPriceMax, "'", "''") & " )) " & varSQL & " "

rspropertyresults.Source = rspropertyresults.Source& "ORDER BY ContentPrice " & Replace(rspropertyresults__varSortWay, "'", "''") & " "

rspropertyresults.CursorType = 0
rspropertyresults.CursorLocation = 2
rspropertyresults.LockType = 1
rspropertyresults.Open()

rspropertyresults_numRows = 0
%>

然而,客户要求不要只匹配其中一个值,而是需要以这样的方式工作:如果说街道和城镇匹配,然后通过电子邮件发送该地产代理或者城镇和邮政编码匹配,那么就发送电子邮件该物业代理人。

您可以想象,我认为查询会变得非常复杂,但我不确定如何最好地设计这样的查询。

我想知道是否有人可以帮助或指出我正确的方向?

4 个答案:

答案 0 :(得分:4)

SELECT  *
FROM    (
        SELECT  id
        FROM    (
                SELECT  id
                FROM    VWTenantPropertiesResults
                WHERE   ContentStreet = 'Holderness Road'
                UNION ALL
                SELECT  id
                FROM    VWTenantPropertiesResults
                WHERE   ContentTown = 'Hull'
                UNION ALL
                SELECT  id
                FROM    VWTenantPropertiesResults
                WHERE   ContentPostCode = 'HU'
                ) qi
        GROUP BY
                id
        HAVING  COUNT(*) >= 2
        ) q
JOIN    VWTenantPropertiesResults r
ON      r.id = q.id
WHERE   ContentBedrooms BETWEEN 1 AND 4
        AND ContentPrice BETWEEN 50 AND 500
ORDER BY
        ContentPrice

这将返回至少2条件匹配的所有记录。

此解决方案是索引友好的:与OR子句不同,它将使用ContentStreetContentTownContentPostCode上的索引。

请参阅我的博客中的此条目,了解效果详情:

为获得最佳性能和安全性,请使用绑定参数替换替换参数值。

这将节省您查询解析的时间,并保护您免受SQL注入。

答案 1 :(得分:3)

在您的网站中包含SQL是不好的做法IMO。但我不熟悉asp-classic。此外,您执行此操作的方式也存在SQL注入的危险。不要混用UI和数据访问逻辑。

查看http://en.wikipedia.org/wiki/SQL_injection

答案 2 :(得分:1)

创建一个SQL存储过程以处理您描述的逻辑是个好主意。在ASP代码中,您可以使用用户提供的参数调用此过程。这避免了动态创建SQL的问题,也使这个问题更容易解决。

有关将ADODB与存储过程一起使用的一些示例,请参阅http://authors.aspalliance.com/stevesmith/articles/sprocs.asp

答案 3 :(得分:0)

我在类似情况下使用的方法是,如果您使用LIKE而不是column = value,那么您可以在任何字段组合中使用任何值。例如:

城镇LIKE('%'+ @town +'%')和zip LIKE('%'+ @ zip'%')和街道LIKE('%'+ @street'%')等等

然后如果他们只填写了一些字段就没关系,它仍然会返回有效的结果。这种方法的主要内容是,所有字段都需要是字符串值,因为LIKE不适用于数字类型列。所以你必须对数字字段进行一些转换,这可能会使一些事情陷入困境,这取决于需要进行多少转换,所以这是一种给予和采取的情况。

我也同意这应该在存储过程中完成传递要搜索的字段的参数。