【问题标题】:Issues incrementing a field in MySQL/PHP with prepared statements使用准备好的语句在 MySQL/PHP 中增加字段的问题
【发布时间】:2011-10-20 11:09:17
【问题描述】:

我有以下代码,假设在准备好的 PHP mysql 语句中将字段值增加 1:

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)。

我错过了什么?

编辑:解决了这个问题。

NB 的评论一针见血——绑定列名会导致它被引用,这会使查询无效。谢谢!

【问题讨论】:

  • 字符。问题似乎与 ajax->values 脚本无关,而是与准备好的语句有关 - :votetype 似乎没有正确准备
  • 您不应该在准备好的语句中绑定列名。为什么?因为他们被引用了。你的:votetype 实际上是'votetype'。它可能报告了一个错误,但我看不到你在哪里捕获它。
  • 如果它是你声称增加其价值的字符?

标签: php mysql field increment


【解决方案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
     ';
    

    【讨论】:

    • 这太好了,谢谢!这是我第一次使用任何类型的数据库,这种解释非常有帮助。
    猜你喜欢
    • 2015-09-15
    • 2014-06-30
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多