Проблемы с увеличением поля в MySQL / PHP с помощью подготовленных операторов

#php #mysql #field #increment

#php #mysql #поле #увеличение

Вопрос:

У меня есть следующий код, который должен увеличивать значение поля на 1 в подготовленном операторе PHP mysql:

 function db_OP_doVote($pdo, $postid, $votetype)
{
    $prepStatement = $pdo->prepare(
        "UPDATE content_posts SET `:votetype` = `:votetype`   1 WHERE `id` = :id"
    );

    $prepStatement->execute(array(':votetype' => $votetype, ':id' => $postid));

    echo "Success";
}
  

Однако это ничего не дает. Ошибка о неправильном синтаксисе SQL не выдается, и скрипт выполняется до завершения, но мое поле вообще не обновляется.

Значения для этого скрипта передаются через jQuery post() в этот скрипт:

 //isset checking here
$postID = (int)$_POST['id'];
$voteType = $_POST['type'];

if ($voteType == "y")
{
    $trueType = "v-cool";
}
elseif ($voteType == "m")
{
    $trueType = "v-meh";
}
elseif ($voteType == "n")
{
    $trueType = "v-shit";
}
else 
{
    die();
}

$db = db_Connect();

db_OP_doVote($db, $postID, $trueType);
  

Который также, по-видимому, фильтрует значения и отправляет их нормально. Я не могу понять, в чем может быть проблема. Увеличиваемое поле является BIGINT(20).

Чего мне не хватает?

РЕДАКТИРОВАТЬ: решена проблема.

Комментарий N.B попал в самую точку — привязка имени столбца приводит к его заключению в кавычки, что делает запрос недействительным. Спасибо!

Комментарии:

1. символ. проблема, похоже, связана не со сценарием ajax-> values, а с подготовленными операторами -:votetype, похоже, не готовится должным образом

2. Вы не должны связывать имена столбцов в подготовленных операторах. Почему? Потому что они попадают в кавычки. Ваш :votetype действительно будет 'votetype' . Вероятно, он сообщает об ошибке, но я не вижу, где вы ее улавливаете.

3. если это символ, как вы утверждаете, чтобы увеличить его значение?

Ответ №1:

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

из вопроса кажется, что ваша настройка неверна.

у вас должна быть другая таблица с голосами и типами голосов в качестве данных.

Ответ №2:

Вы не можете параметризовать имена столбцов с помощью PDO. Что вы можете сделать, это иметь жестко запрограммированные значения (которые у вас в основном уже есть) и соответствующим образом сконструировать строку SQL. Я бы тоже проверил это значение в фактической функции, просто на всякий случай:

 function db_OP_doVote($pdo, $postid, $votetype)
{
    if( !in_array( $votetype, array( 'v-cool', 'v-meh', 'v-shit' /*, etc. */ ), true ) )
    {
        throw new InvalidArgumentException( 'Unexpected $votetype: ' . $votetype );
        // or simply return false perhaps
    }

    $sql = '
        UPDATE content_posts
        SET `' . $votetype . '` = `' . $votetype . '`   1
        WHERE `id` = :id
    ';

    $prepStatement = $pdo->prepare( $sql );

    $prepStatement->execute(array(':id' => $postid));

    echo "Success";
}
  

Однако эта стратегия предполагает, что вашему дизайну базы данных может потребоваться немного больше внимания. То, как у вас есть сейчас, заключается в том, что для каждого типа голосования у вас есть столбец. Это не очень эффективный и / или гибкий дизайн базы данных. Что произойдет, если вас попросят добавить другой тип голосования?

Я бы предложил добавить еще одну таблицу, чтобы быть более гибкой:

 CREATE TABLE `content_post_vote` (
  `content_post_id` int(11) NOT NULL,
  `vote_type` enum('cool','meh','shit') NOT NULL, # using enum() to assure valid vote types 
  `votes` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`content_post_id`,`vote_type`)
)
  

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

 $sql = '
    INSERT INTO `content_post_vote` (`content_post_id`,`vote_type`,`votes`)
    VALUES( :id, :votetype, 1 )
    ON DUPLICATE KEY UPDATE `votes` = `votes`   1
';
  

Что это делает, так это вставляет голосование, если для определенного первичного ключа ( content_post_id , vote_type ) еще нет записи, и еще обновляет запись голосованием, если запись уже существует.

Затем, чтобы запросить базу данных о том, сколько голосов определенного типа content_post получил конкретный, вы делаете это:

  $sql = '
     SELECT `votes` # or perhaps more columns
     FROM `content_post_vote`
     WHERE `content_post_id` = :id AND 
           `vote_type` = :votetype
 ';
  

Комментарии:

1. Это отлично, спасибо! Я впервые работаю с базами данных любого типа, и такого рода объяснения чрезвычайно полезны.