Constructing a good search query using system.data.oracleclient

让人想犯罪 __ 提交于 2019-12-01 10:02:50

问题


I am constructing a search function in a class to be used by several of our asp pages. The idea is simple, take a search term from the user and query the database for the item. Currently I am doing this the wrong way, which is vulnerable to SQL injection attacks (and ELMAH is in there to save the day if something goes wrong):

Public Shared Function SearchByName(ByVal searchterm As String) As DataTable
    SearchByName = New DataTable

    Dim con As New OracleConnection(System.Configuration.ConfigurationManager.ConnectionStrings("OracleDB").ConnectionString)



    Try
        con.Open()
        Dim SqlStr As String = "select ID_ELEMENT, ELEMENT_NAME from table_of_elements where upper(ELEMENT_NAME) like upper('%" & searchterm & "%')"
        Dim cmd As New OracleCommand(SqlStr, con)
        SearchByName.Load(cmd.ExecuteReader)





    Catch ex As Exception
        Elmah.ErrorSignal.FromCurrentContext().Raise(ex)

    End Try
    con.Close()
    con.Dispose()




    Return SearchByName
End Function

String concatenation is BAD. Next thing you know, Bobby Tables wrecks my system. Now, the correct way to do this is to to make a proper oracle variable, by putting :searchterm in the string and adding the following line:

cmd.Parameters.Add(New OracleParameter("SEARCHTERM", searchterm))

The problem is since I am using a like statement, I need to be able to have % on either side of the search word, and I can't seem to do that with '%:searchterm%', it just gives an error of ORA-01036: illegal variable name/number.

Can I parameterize but still have my flexible like statement be a part of it?


回答1:


Instead of doing the concatenation in your VB code, do the concatenation in the SQL statement. Then what you're trying to do should work. Here's some SQL illustrating what I'm talking about:

select ID_ELEMENT, ELEMENT_NAME 
from table_of_elements 
where upper(ELEMENT_NAME) like ('%' || upper(:searchterm) || '%')

BTW, you might end up with more efficient queries if you switch the collaction on ELEMENT_NAME to case-insensitive and then remove the calls to upper().




回答2:


Since you're using oracle, another option would be to use Oracle Text to perform the search.

It can take a bit to set up properly, but if you have a large amount of text to search, or have some sort of structured data, it can offer you many more options than a simple wild-card comparison.

It also has some nice features for dealing with multiple languages, if you happen to have that problem as well.



来源:https://stackoverflow.com/questions/1412023/constructing-a-good-search-query-using-system-data-oracleclient

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!