Как динамически генерировать SQL-запрос на основе выбора пользователя? - PullRequest
2 голосов
/ 11 января 2010

Мне нужно создать графический интерфейс, с помощью которого пользователи могут выбрать несколько атрибутов, которые будут использоваться для запроса базы данных, чтобы найти подходящих людей. Я ищу идеи, как динамически генерировать запрос к базе данных в соответствии с выбором пользователя.

Запрос будет содержать несколько полей, но чтобы понять, я приведу в качестве примера только три из них:

  • Занятие - может быть от 0 до n строк занятости. Если заданы строки занятия, одна из них должна соответствовать.

  • Возраст - возраст может быть задан как:

    1. точное совпадение (30)
    2. диапазон (например, 30-40)
    3. меньше значения (-40)
    4. больше значения (30 -)

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

  • Рост - аналогично возрасту

Примеры запросов:

Нет критериев:

select * from persons

Дано только занятие:

select * from persons where occupation = 'dentist'

Было дано несколько занятий:

select * from persons where (occupation = 'dentist' or occupation = 'engineer')

Возраст указан как значение, превышающее значение, и он должен существовать в профиле человека:

select * from persons where age >= 30

Рост указан как диапазон, и он не обязательно должен присутствовать в профиле человека:

select * from persons where (height is null or (height >= 30 and height <= 40))

Сочетание разных критериев:

select * from persons where occupation = 'dentist' and age >= 30 and (height is null or (height >= 30 and height <= 40))

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

Ответы [ 3 ]

3 голосов
/ 11 января 2010

Попробуйте что-то вроде Zend_Db_Select. Он предоставляет (свободный) интерфейс для генерации запросов и обрабатывает создание синтаксиса для вас, например,

$select = $db->select();
$select->from( /* ...specify table and columns... */ )
       ->where( /* ...specify search criteria... */ )
       ->where( /* ...specify other criteria... */ )
       ->order( /* ...specify sorting criteria... */ );

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

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

    request = Request->getParams()            // selection criteria set from GUI
    sql     = Products->getBaseQuery(request) // basic query for requested View
    sql     = Decorator->applyUserConfig(sql) // custom fixed user filter
    results = sql->execute()
2 голосов
/ 11 января 2010

Это не даст прямого ответа на ваш вопрос, но вот небольшой совет для вас, вместо того, чтобы писать запрос следующим образом:

select * from persons where (occupation = 'dentist' or occupation = 'engineer')

Попробуйте это:

select * from persons where occupation IN ('dentist','engineer')

Это легче для чтения и легко для генерации PHP-скрипта.

0 голосов
/ 11 января 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...