Mysql update и массив

Рейтинг: 2Ответов: 2Опубликовано: 12.03.2015

Имеется запрос:

UPDATE `table` SET `position` = ? WHERE `id` = ?

Еще имеется массив, id => position:

$replace = array(1 =>0, 5 => 1, 7 => 2);

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

Вопрос:
как можно составить запрос к базе, чтобы получить правильный результат?

Ответы

▲ 2

Можно, но не нужно, проделать это в цикле, результат будет верным, но реализация паршива.

Всё ровно наоборот. Можно, но ни в коем случае не стоит это делать одним запросом.

Если нам надо обновить 10 записей, то надо сделать 10 запросов. Это азбука работы с БД. Никакой проблемы выполнить 10 запросов нету.

Но зато есть проблема с использованием неверного инструмента для этой цели. Запрос INSERT INTO, который посоветовали в комментах - он, вообще-то, если кто не заметил - на ВСТАВКУ. А не на обновление. А это значит, что он ВСТАВЛЯЕТ записи. И - будте уверены - ВСТАВИТ. Запись, которая уже была удалена. Если 10 запросов на обновление найдут только 9 подходящих записей, то обновят только 9 записей. А запрос на вставку обновит 9, а потом вставит еще одну.

То есть INSERT INTO c ON DUPLICATE - это не красивая замена 10 запросам UPDATE, а совершенно другой запрос.

Судя по знакам вопроса в запросе, у автора уже используются подготовленные выражения. то есть механизм - СПЕЦИАЛЬНО придуманный для множественного запроса. И остается только написать простой код

$replace = array(1 =>0, 5 => 1);
$stmt = $pdo->prepare("UPDATE `table` SET `position` = ? WHERE `id` = ?");
foreach ($replace as $id -> $position)
{
    $stmt->execute(array($position, $id));
}

И впредь любые инструменты использовать строго по назначению.

▲ 2

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

foreach ($replace as $k => v) {
  $values[] = "({$k}, {$v})";
}
$str = join(',', $values);
$sql = "INSERT INTO `table`(`id`, `position`) VALUES
       {$str}
       ON DUPLICATE KEY UPDATE 
       `id`=VALUES(`id`), `position`=VALUES(`position`)";