【问题标题】:PHP PDO UPDATE statement with subquery带有子查询的 PHP PDO UPDATE 语句
【发布时间】:2018-10-05 04:55:21
【问题描述】:

我正在尝试使用 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]:无效参数号

【问题讨论】:

  • “它在执行时就失败了”。它不只是失败。它抛出一个错误,将错误发布给我们!
  • 冷静一下。致命错误:未捕获的 PDOException:SQLSTATE[HY093]:无效参数号
  • 答案就在错误上。您的查询中有 5 个参数,但您只绑定了 4 个参数(您必须重复 :gameid

标签: php mysql pdo subquery


【解决方案1】:

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

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


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

将绑定占位符名称更改为不同/唯一。此处显示,将出现的:gameid 之一更改为:gameid2

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

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

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

【讨论】:

  • 嗯,这确实解决了我的问题。我很确定我可以使用绑定到单个参数的 :gameid 的 2 个实例。但是,您的逻辑是合理的,我理解这个问题。非常感谢。
  • 我们可以在一个语句中的多个位置引用同一个命名占位符,这并不罕见。 (我们可以使用其他数据库/驱动程序,例如 Perl DBD::Oracle。)当我遇到问题时,我找不到有关 PDO 限制的文档。我发现的只是 PDO 文档没有显示任何重用相同占位符的示例。那么,它是有记录的吗?
猜你喜欢
  • 2013-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多