Построение MySQL-запроса на основе опубликованных переменных - PullRequest
3 голосов
/ 07 августа 2009

Это кажется такой простой задачей, но мне трудно найти решение, которое мне нравится для этого. Я не могу найти ничего, что я бы рассматривал, кроме как неуклюжий. Вот с чем я работаю:

Существует форма поиска, которая публикует переменные в сценарии обработки. Эти переменные являются фильтрами запрашиваемых данных. В зависимости от прав пользователя, может появиться больше или меньше переменных, в зависимости от фильтров, к которым у них есть доступ. Каждый фильтр ссылается на поле в таблице, из которой получены результаты. Одна опция для каждого фильтра также «ЛЮБАЯ», поэтому предложение WHERE не требуется.

Какой хороший способ построить строку запроса. Допустим, возвращаются четыре переменные: $ firstname, $ lastname, $ age, $ dob. Но только некоторые пользователи имеют доступ к фильтрам по $ age и $ dob.

$query = "SELECT * FROM people";
if(($firstname != 'ANY' && !empty($firstname)) ||
   ($lastname != 'ANY' && !empty($lastname)) ||
   ($age != 'ANY' && !empty($age)) ||
   ($dob != 'ANY' && !empty($dob))) {
    $query .= " WHERE";
}

if($firstname != 'ANY' && !empty($firstname)) {
    $query .= " firstname='$firstname'";
}
if($lastname != 'ANY' && !empty($lastname)) {
    if($firstname != 'ANY' || !empty($firstname)) {
        $query .= " AND";
    }
    $query .= " lastname='$lastname'";
}
...

И так далее. Но это выглядит глупо, ужасно и смехотворно неэффективно для меня. Я использую слегка измененный шаблон MVC, поэтому имеет ли смысл создавать методы в модели поиска для каждого возможного фильтра?

Ответы [ 3 ]

5 голосов
/ 07 августа 2009

Я бы пошел на это:

$query = "SELECT * FROM people";

$whereClause = " WHERE 1 = 1 ";
if($firstname != 'ANY' && !empty($firstname)) {
    $whereClause .= " AND firstname='$firstname' ";
}
if($lastname != 'ANY' && !empty($lastname)) {
    $whereClause .= " AND lastname='$lastname' ";
}

$query .= $whereClause;

Вы можете альтернативно собрать все операторы в массив и просто перейти:

if (count($arr)>0) { 
   $query = "$query 
              WHERE ". implode(" AND ",$arr); 
}
0 голосов
/ 07 августа 2009

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

foreach($_POST as $name=>$value){
    $arrFields[] = $name." = '".$value."'";
}
$sSql = "SELECT * FROM people WHERE 1 AND ".implode(" AND ",$arrFields);

ИЛИ если ваши имена полей не совпадают с именами таблиц или если вы хотите обрабатывать поля в SQL по-разному, вы можете использовать переключатель.

foreach($_POST as $name=>$value){
    switch($name){
        case "firstname":
            $arrFields[] = "fName = '".$value."'";
            break;
        case "lastname":
            $arrFields[] = "lName = '".$value."'";
            break;
        case "age":
            $arrFields[] = "bioAge >= ".$value;
            break;
    }
}
$sSql = "SELECT * FROM people WHERE 1 AND ".implode(" AND ",$arrFields);
0 голосов
/ 07 августа 2009

Вы можете расширить это:

http://code.google.com/p/mysql-query-builder/

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