Создание хорошего поискового запроса с использованием system.data.oracleclient

Я создаю функцию поиска в классе, которая будет использоваться несколькими нашими страницами asp. Идея проста: возьмите поисковый запрос от пользователя и запросите элемент в базе данных. В настоящее время я делаю это неправильным способом, который уязвим для атак путем внедрения SQL (и ELMAH). там, чтобы спасти день, если что-то пойдет не так):

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

Конкатенация строк ПЛОХАЯ. Следующее, что вы знаете, Bobby Tables разрушает мою систему. Теперь правильный способ сделать это — создать правильную переменную оракула, поместив :searchterm в строку и добавив следующую строку:

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

Проблема в том, что, поскольку я использую подобное выражение, мне нужно иметь % по обе стороны от поискового слова, и я не могу сделать это с «%: searchterm%», это просто дает ошибку ORA-01036: Недопустимое имя/номер переменной.

Могу ли я параметризовать, но по-прежнему иметь в своем составе гибкое подобное выражение?


person Maximillian    schedule 11.09.2009    source источник


Ответы (2)


Вместо того, чтобы выполнять конкатенацию в вашем коде VB, сделайте конкатенацию в операторе SQL. Тогда то, что вы пытаетесь сделать, должно работать. Вот некоторый SQL, иллюстрирующий то, о чем я говорю:

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

Кстати, вы можете получить более эффективные запросы, если вы переключите сопоставление ELEMENT_NAME на нечувствительный к регистру, а затем удалите вызовы upper().

person Justin Grant    schedule 15.09.2009
comment
Я собираюсь проверить это очень быстро. Если это сработает, вы станете счастливым обладателем 100 блестящих новых представителей. - person Maximillian; 16.09.2009

Поскольку вы используете Oracle, другим вариантом может быть использование Oracle Text для выполнения поиска.

Для правильной настройки может потребоваться некоторое время, но если у вас есть большой объем текста для поиска или у вас есть какие-то структурированные данные, он может предложить вам гораздо больше возможностей, чем простое сравнение с подстановочными знаками.

У него также есть несколько приятных функций для работы с несколькими языками, если у вас тоже возникла эта проблема.

person chris    schedule 15.09.2009
comment
Моя проблема немного более узкая, чем та, для которой предназначена ваша ссылка, но она делает чтение очень интересным, и я хотел бы поблагодарить вас за это. - person Maximillian; 16.09.2009