MySQL запрос в цикле foreach - PullRequest
       6

MySQL запрос в цикле foreach

0 голосов
/ 30 августа 2011

Я хочу показать все текстовые сообщения из БД, где id=$e ($err - массив).
Вставил запрос в цикл foreach, он работает хорошо, но выполняет дополнительную работу (выполняет запрос для каждого значения массива).
Есть ли другой способ сделать это (я имею в виду извлечь запрос из цикла foreach)?
Мой код выглядит так.

foreach ($err as $e) 
{
$result = $db -> query("SELECT * from err_msgs WHERE id='$e'");
$row = $result -> fetch_array(MYSQLI_BOTH);
echo "<li><span>".$row[1]."</span></li>";
}

Ответы [ 4 ]

4 голосов
/ 30 августа 2011

Гораздо эффективнее это сделать с помощью implode () , поскольку это приведет только к одному запросу к базе данных.

if (!$result = $db->query("SELECT * FROM `err_msgs` WHERE `id`='".implode("' OR `id`='",$err)."'")) {
  echo "Error during database query<br />\n";
  // echo $db->error(); // Only uncomment this line in development environments. Don't show the error message to your users!
}
while ($row = $result->fetch_array(MYSQLI_BOTH)) {
  echo "<li><span>".$row[1]."</span></li>\n";
}
1 голос
/ 30 августа 2011

Во-первых, небольшая лекция: встраивание строк непосредственно в ваши запросы в какой-то момент вызовет у вас проблемы (точнее, проблемы, связанные с внедрением SQL), постарайтесь избежать этого, если это возможно.Лично я использую библиотеку PDO PHP, которая позволяет связывать параметры, а не создавать строку.

Что касается вашего вопроса, я не уверен, что понял.Вы говорите, что он выполняет дополнительную работу, вы имеете в виду, что он возвращает правильные результаты, но неэффективно?Если это так, то это тоже можно решить с помощью PDO.Вот идея.

Шаг 1: Подготовьте свое утверждение, поместив заполнитель туда, где у вас есть $ e. Шаг 2: Переберите $ err, в теле цикла вы зададите для заполнителя значениетекущее значение $ e

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

Какой-то фактический код будет выглядеть следующим образом:

// Assume that $dbdriver, $dbhost and $dbname have been initialised
// somewhere. For a mysql database, the value for $dbdriver should be
// "mysql".

$dsn = "$dbdriver:host=$dbhost;dbname=$dbname";
$dbh = new PDO($dsn, $dbuser, $dbpassword); 

$qry = "SELECT * from err_msgs WHERE id = :e"
$sth = $dbh->prepare($qry);

foreach ($err as $e) {
    $sth->bindParam(":e", $e);
    $sth->execute();
    $row = $sth->fetch();

    // Prints out the *second* field of the record
    // Note that $row is also an associative array so if we
    // have a field called id, we could use $row["id"] to 
    // get its value
    echo "<li><span>".$row[1]."</span></li>";
}

Один последний момент, если вы хотите просто выполнить запрос один раз, вместо этоговыполнение его внутри цикла, это возможно, но, опять же, может не привести к улучшению производительности.Это может быть достигнуто с использованием синтаксиса IN.Например, если меня интересуют записи с идентификатором в наборе {5, 7, 21, 4, 76, 9}, я бы сделал:

SELECT * из err_msgs WHERE id IN (5, 7, 21, 4, 76, 9)

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

1 голос
/ 30 августа 2011

Проверьте предложение SQL IN .

0 голосов
/ 30 августа 2011

Вы можете сделать это намного проще, выполнив

$err_csv = implode("','",$err);
$sql = "SELECT FROM err_msgs WHERE id IN ('$err_csv')";
$result = $db -> query($sql);
while ($row = $result -> fetch_array(MYSQLI_BOTH)) 
{
   echo "<li><span>".$row[1]."</span></li>";
}

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

Ссылки:
http://php.net/manual/en/function.implode.php

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