Построение хорошего поискового запроса с использованием system.data.oracleclient - PullRequest
1 голос
/ 11 сентября 2009

Я создаю функцию поиска в классе, который будет использоваться несколькими нашими страницами 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

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

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

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

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

Ответы [ 2 ]

4 голосов
/ 16 сентября 2009

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

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

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

1 голос
/ 16 сентября 2009

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

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

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

...