问题 SQLSTATE [HY093]:参数号无效:没有绑定参数,但提供了参数


我正在构建一个连接的数据库对象 PDO 对象 PDOStatement 对象以便链接可用。基本上我只是把我经常使用的方法,但是 bindParam 给了我一个艰难的时刻。

private $stmt = null;

...

public function prepare($statement,array $driver_options = array()) {
    if($this->stmt) throw new \Exception('PDO Statement already prepared, no override!');
    $this->stmt = parent::prepare($statement, $driver_options);
    return $this;
}

public function bindParam($place, &$val, $dataType){
    if(!$this->stmt) throw new \Exception('PDO Statement is empty');
    $this->stmt->bindParam($place, $val, $dataType);
    return $this;
}

public function execute(array $params = array()){
    if(!$this->stmt) throw new \Exception('PDO Statement is empty');
    $this->stmt->execute($params);
    return $this;
}

public function fetchAll($pdoFetchType){
    if(!$this->stmt) throw new \Exception('PDO Statement is empty');
    return $this->stmt->fetchAll($pdoFetchType);
}

...

public function getStmt(){
    return $this->stmt;
}

public function clearStmt(){
    $this->stmt = null;
}

我在这段代码中从标题中得到错误:

$i = 0;
$db->prepare('SELECT * FROM users LIMIT ?,1')->bindParam(1, $i, \PDO::PARAM_INT);
while($row = $db->execute()->fetchAll(\PDO::FETCH_ASSOC)){
    echo "<pre>".print_r($row, true)."</pre>";
    $i++;
}

基本上我发现的关于这个错误的是它在提供变量时发生 bindParam 是 null但是 $i 显然不是空的。你能帮我吗?

编辑:还在跑步

var_dump($this->stmt->bindParam($place, $val, $dataType));

在里面 bindParam 方法返回 TRUE。从手册:

返回值

成功时返回TRUE,失败时返回FALSE。

它成功但没有绑定参数???我觉得我的大脑很快就会爆炸。


4410
2017-12-07 02:14


起源

如果你放了会发生什么 var_dump($val) 在你定义的内部 bindParam()?如果你放 var_dump($this->stmt)? - Francisco Presencia
@FranciscoPresencia int(0)  object(PDOStatement)#6 (1) { ["queryString"]=> string(29) "SELECT * FROM users LIMIT ?,1" } 我真的很讨厌它 php 对我这样做.. - php_nub_qq
我的想法已经用完了,试试吧 bindValue() 代替 bindParam() 在你的功能里面 public function bindParam 看看是否有变化。来自doc, 与PDOStatement :: bindValue()不同,变量被绑定为引用,并且仅在调用PDOStatement :: execute()时进行计算。 但我不确定它是否会改变任何东西。 - Francisco Presencia
@FranciscoPresencia即使错误信息保持不变,至少可以改变.. Q_Q - php_nub_qq
调试器是你的朋友。 - mingos


答案:


我想使用参考 &$val 而不是一个值 $val 是导致问题的原因。

请尝试使用此代码:

public function bindParam($place, $val, $dataType)
{
    if(!$this->stmt) throw new \Exception('PDO Statement is empty');
    $this->stmt->bindParam($place, $val, $dataType);
    return $this;
}

编辑

我的上述答案是错误的。

尝试修改 execute 方法:

public function execute(array $params = array()){
    if(!$this->stmt) throw new \Exception('PDO Statement is empty');
    $this->stmt->execute();
    return $this;
}

将空数组作为参数传递给 execute 方法删除所有以前的绑定。这就是为什么 bindParam 返回true(成功绑定),但是一旦你打电话,就会出现“没有参数被绑定”的错误 execute


12
2017-12-07 03:06



它曾经没有参考,仍然有同样的错误。我添加了引用,因为没有它,包装父进程 bindParam 这样没有意义 - php_nub_qq
参考文献很危险,很容易破坏。请尝试运行循环并调用 bindParam 在每次迭代中都有更新的 $i 价值而不是依赖于参考。我相信它会按预期工作。 - mingos
它没有。当正确使用时,引用并不危险。如果是原件 PDO功能 bindParam 使用参考,然后必须有一个很好的理由,因为有。无论如何,我尝试了你的建议,遗憾的是,错误是一样的。 - php_nub_qq
我特此退出关于您所谓的参考误用的声明 - 请参阅我编辑的答案。 - mingos
其中一件事让你想要“我怎么没看到这个”。先生非常感谢您! - php_nub_qq


得到了同样的错误,但原因不同

我的要求有评论,其中一个包括该死的 问号
对于PDO,“?“当然是一个要绑定的参数。

我的请求在其他任何地方都没有问题,我不知道PDO在我没有使用任何内容时会发明一个“参数”,因为我总是使用命名占位符,比如  :value


花了一个多小时就这个:(
 愿这个答案可以帮助一些人解决这个愚蠢的问题。


3
2018-02-14 13:26