带有子查询的PHP PDO UPDATE语句

时间:2018-04-24 20:06:19

标签: php mysql pdo subquery

我尝试使用PDO创建查询,其中查询包含子查询。代码不起作用。使用工作台,我可以进行查询,但确实可以执行。

在使用PDO时,我觉得这里有一个细微差别。

    $turn = 1;
    $phase = -1;
    $status = "waiting";
    $gameid = 1;

        $stmt = $this->connection->prepare("
            UPDATE playerstatus 
            SET 
                turn = :turn,
                phase = :phase,
                status = :status,
                value = value + (SELECT reinforce FROM games where id = :gameid)
            WHERE
                gameid = :gameid                
        ");

        $stmt->bindParam(":turn", $turn);
        $stmt->bindParam(":phase", $phase);
        $stmt->bindParam(":status", $status);
        $stmt->bindParam(":gameid", $gameid);

        $stmt->execute();

我尝试了很多调整,它只是在执行时失败了。

编辑错误:

  

致命错误:未捕获PDOException:SQLSTATE [HY093]:参数号无效

1 个答案:

答案 0 :(得分:2)

PDO名为placholders的已知(但没有很好记录)限制:同一个绑定占位符在语句中不能使用多次。解决方法是使用不同的绑定占位符名称。

(PDO中的这个限制可能已经在以后的版本中解决了(?)。我认为根本原因是"在幕后",PDO正在用位置符号问号替换命名的占位符。此问题不仅限于UPDATE语句,同样的问题困扰所有使用命名占位符的PDO SQL语句。)

此外,与问题无关,我建议使用bindValue代替bindParam

将绑定占位符名称更改为distinct / unique。此处显示,将:gameid的某个匹配项更改为:gameid2

           value = value + (SELECT reinforce FROM games where id = :gameid)
        WHERE
            gameid = :gameid2
                            ^

我们需要为每个绑定占位符提供一个值。这意味着我们需要添加另一条线。使用bindValue,我们可以引用相同的变量,而无需复制它。

    $stmt->bindValue(":gameid", $gameid);
    $stmt->bindValue(":gameid2", $gameid);
                             ^