MySQL Query с несколькими WHERE, некоторые могут быть пустыми - PullRequest
2 голосов
/ 12 мая 2011

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

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

Как я могу это сделать? Большое спасибо за помощь!

@ Ибу, вот что у меня есть:

// Now we need to query the database for these terms
$sql_query = "SELECT * FROM `students` WHERE `first_name` = '" . $first_name . "' AND `last_name` = '" . $last_name . "' AND `nick_name` = '" . $nick_name . "' AND `grade` = '" . $grade . "' AND `gender` = '" . $gender . "'";
$result = mysql_query($sql_query);

// Let's check to make sure there is an actual result
$num_rows = mysql_num_rows($result);

if($num_rows < 1) {
    echo 'No student was found using that criteria.';
}

if($num_rows >= 1) {
    echo '<p>' . $num_rows . ' result(s) found. Below are the results:</p>';
    echo '<br />';
}

while($row = mysql_fetch_array($result)) {
    echo '
        <table border="1" width="400">
        <tr>
            <td colspan="2" align="center">Student Profile - ' . $row['last_name'] . ', ' . $row['first_name'] . '</td>
        </tr>
        <tr>
            <td>First Name: </td>
            <td>' . $row['first_name'] . '</td>
        </tr>
        <tr>
            <td>Last Name: </td>
            <td>' . $row['last_name'] . '</td>
        </tr>
        <tr>
            <td>Nick Name: </td>
            <td>' . $row['nick_name'] . '</td>
        </tr>
        <tr>
            <td>Grade: </td>
            <td>' . $row['grade'] . '</td>
        </tr>
        <tr>
            <td>Gender: </td>
            <td>' . $row['gender'] . '</td>
        </tr>
        </table> <br /><br />';

}

Ответы [ 5 ]

2 голосов
/ 12 мая 2011

Erland Sommarskog является фактическим источником в этом вопросе:
http://www.sommarskog.se/dyn-search-2005.html#conclusion

Я бы написал каждый параметризованный AND в таком формате:

...AND ((@Param IS NULL)  OR (@Param = your_column))
1 голос
/ 12 мая 2011

Я обычно предпочитаю создавать «чистые» запросы, динамически создавая предложение WHERE. При условии, что вы правильно очистили данные из $_POST и скопировали их в $data с ключами в $data, названными в честь полей, которые они будут использовать для фильтрации:

$sql = "SELECT ..fields.. FROM ..table..";
$search_enabled_fields = array('firstname', 'lastname', 'email', /* ..etc.. */);
$conditions = array();
foreach ($search_enabled_fields as $field) {
  if (!empty($data[$field])) { // isset and not an empty string
    $value = $data[$field];
    // maybe you could sanitize $value here if you didn't before..
    $conditions[] = "$field = '$value'";
  }
}
if (count($conditions) > 0) {
  $sql .= " WHERE ". implode(' AND ', $conditions);
}
// now, execute your $sql query..

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

1 голос
/ 12 мая 2011

Возможно, вы захотите построить SQL-запрос динамически. Прочитайте сообщение в блоге Гейл Шоу на Catch-all запросах .

0 голосов
/ 12 мая 2011
$query = "select * from somewhere where 1 = 1";
if(isset($_POST['something'])){
  $query .= " and something = '{$_POST['something']}'";
}
if(isset($_POST['something_else'])){
  $query .= " and something_else = '{$_POST['something_else']}'";
}

и т. Д.но с экранированным вводом

1 = 1, чтобы избежать необходимости проверять, нужно ли добавлять ключевое слово where

0 голосов
/ 12 мая 2011

Просто проверьте $_POST vars и создайте запрос на этом.

Например, вот так (это плохо, потому что он не очищает $_POST для инъекции, но это хорошее начало):

$whereSet = false;
$where = '';
if(isset($_POST['name'])){
    $whereSet = true;
    $where .= "WHERE name = '{$_POST['name']}'\n";
}
if(isset($_POST['nick'])){
    if(!$whereSet){
        $where .= "WHERE ";
        $whereSet = true;
    }
    else {
        $where .= "AND ";
    }
    $where .= "nick = '{$_POST['nick']}'\n";
}
//...etc

Затем просто добавьте переменную $where в конец вашего запроса

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