2011-10-20 37 views
0

我有下面的代码是应该 1在一份PHP MySQL的语句来增加一个字段值:问题在MySQL/PHP递增场预处理语句

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后()这个脚本反馈:

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

我错过了什么?

编辑:解决了这个问题。 012BJ的评论点击头部 - 绑定列名会导致它被引用,这会使查询无效。谢谢!

+0

votetype是int或字符? :S – JellyBelly

+0

char。该问题似乎不是与ajax-> values脚本相关,而是与准备好的语句相同 - :votetype似乎没有准备好 – Ephemeralis

+0

您不应该在预准备语句中绑定列名称。为什么?因为他们被引用。你的':votetype'实际上是''votetype''。这可能是报告错误,但我看不到你在哪里捕捉它。 –

回答

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"; 
} 

然而,这种策略意味着你的数据库设计可以使用一些更多的关注。你现在拥有的方式是,对于每种类型的投票,你都有一个专栏。这不是真正有效和/或灵活的数据库设计。如果您被要求添加其他类型的投票,会发生什么?

我建议增加一个表,更灵活:这样做是插入一票,如果没有

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

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

然后将查询会是这样记录某个主键(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 
'; 
+0

+1用于检查白名单中的动态列名称。 – Johan

+0

这很好,谢谢!这是我第一次使用任何类型的数据库,这种解释非常有帮助。 – Ephemeralis

3

您不能使用字段名称的绑定。

从这个问题似乎你的设置是错误的。

你应该有另外一张有票和投票类型的表作为数据。