Как правильно задать запрос UPDATE где название столбца переменная?

Есть таблица со столбцами id, count1, count2,count3
Получаю массив вида {[21-1]=>{[count]=>3},[2-2]=>{[count]=>20},[5-3]=>{[count}=>15}.....}
где 21-1 это id и 1 это номер столбца для изменения значения
Написал код для внесения изменений в таблицу
Всё работает но выглядит как то топорно. как можно улучшить код и как правильно задать запрос если в качестве названия столбца использовать переменную?
$sql = "SELECT `count1`, `count2`, `count3` 
        FROM `list` 
        WHERE `id` = ?";
    foreach($data as $id =>$value ) {
        $count=$value['count'];
        $id=explode("-", $id);
        $stmt = $conn -> prepare ($sql);
        $stmt -> execute([$id[0]]);
        $result = $stmt -> fetch(PDO::FETCH_ASSOC);
        if ($id[1]== '1') {$result=(int)$result['count1']-$count; $column = 'count1';};
        if ($id[1]== '2') {$result=(int)$result['count2']-$count; $column = 'count2';};
        if ($id[1]== '3') {$result=(int)$result['count3']-$count; $column = 'count3';};
        $sql_upd = "UPDATE `list` 
            SET $column = ?
            WHERE `id` = ?";
        $stmt = $conn -> prepare ($sql_upd);
        $stmt -> execute ([$result,$id[0]]);
     }
  • Вопрос задан
  • 365 просмотров
Решения вопроса 1
ipatiev
@ipatiev Куратор тега PHP
Потомок старинного рода Ипатьевых-Колотитьевых
Этот вопрос - прекрасная иллюстрация того факта, что нормализация базы данных - это не блажь оторванных от жизни теоретиков, а насущная необходимость. И её отсутствие приводит к проблемам на ровном месте.

Уже по наличию нумерованных столбцов сразу видно, что структура БД кривая. А текущая проблема делает это еще более наглядным: собственно, сама постановка вопроса, "как задать имя столбца через переменную", говорит о том, что имя колонки используется в условии. То есть оно должно быть значением в строке.

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

UPDATE link_count SET count=count+? WHERE link_id=? and number=?
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Anastasia2306
@Anastasia2306
PHP-разработчик.
Как насчет оператора CASE?

$sql = "UPDATE `list` 
        SET count1 = CASE WHEN id = ? AND ? = 1 THEN count1 - ? ELSE count1 END,
            count2 = CASE WHEN id = ? AND ? = 2 THEN count2 - ? ELSE count2 END,
            count3 = CASE WHEN id = ? AND ? = 3 THEN count3 - ? ELSE count3 END
        WHERE id = ?";

$stmt = $conn->prepare($sql);

foreach ($data as $id => $value) {
    $idParts = explode("-", $id);
    $count = $value['count'];
    $stmt->execute([$idParts[0], $idParts[1], $count, $idParts[0], $idParts[1], $count, $idParts[0], $idParts[1], $count, $idParts[0]]);
}


Здесь используется оператор CASE для обновления нужного столбца в зависимости от значения $idParts[1]. Если $idParts[1] не соответствует ни одному из условий, то значение столбца остается неизменным. Ну и не забываем про подготовленный запрос prepare чтобы избежать возможной инъекции
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы