php SQL状态[HY093]:无效的参数编号:未定义参数

fhg3lkii  于 2023-01-29  发布在  PHP
关注(0)|答案(4)|浏览(206)

我已经使用Yii的活动记录模式有一段时间了。现在,我的项目需要为一个小事务访问一个不同的数据库。我认为Yii的DAO会很好地解决这个问题。然而,我得到了一个神秘的错误。
CDbCommand无法执行SQL语句:SQL状态[HY093]:无效的参数编号:未定义参数
下面是我的代码:

public function actionConfirmation
{
    $model_person = new TempPerson();

    $model = $model_person->find('alias=:alias',array(':alias'=>$_GET['alias']));
    $connection=Yii::app()->db2;
            $sql = "INSERT INTO users (username, password, ssn, surname
                    , firstname, email, city, country) 
                    VALUES(:alias, :password, :ssn, :surname
                    , :firstname, :email, :city, :country)";
            $command=$connection->createCommand($sql);
            $command->bindValue(":username", $model->alias);
            $command->bindValue(":password", substr($model->ssn, -4,4));
            $command->bindValue(":ssn", $model->ssn);
            $command->bindValue(":surname", $model->lastName);
            $command->bindValue(":firstname", $model->firstName);
            $command->bindValue(":email", $model->email);
            $command->bindValue(":city", $model->placeOfBirth);
            $command->bindValue(":country", $model->placeOfBirth);
            $command->execute();
            $this->render('confirmation',array('model'=>$model));
}

这将构造以下查询(如应用程序日志所示):

INSERT INTO users (username, password, ssn, surname, firstname, email
                   , city, country) 
VALUES(:alias, :password, :ssn, :surname, :firstname, :email, :city, :country);

仅供参考$model->placeOfBirth应该是城市和县的值。这不是打字错误(只是我必须做的一件蠢事)。

iklwldmw

iklwldmw1#

为了提供一个答案-因为这个错误是相当常见的-这里有几个原因:

  1. :parameter名称与绑定错误不匹配(输入错误?),这就是这里发生的情况,他们在SQL语句中有:alias,但是绑定了:username,所以当尝试参数绑定时,Yii/PDO无法在SQL语句中找到:username,这意味着它是“少了一个参数”并抛出了一个错误。
    1.完全忘记了为参数添加bindValue(),这在Yii其他结构中更容易做到,比如$critera,这里你有一个数组或params($criteria->params = array(':bind1'=>'test', ':bind2'=>'test))。
    1.另一个可能的原因是invalid character in the placeholder name
    1.在使用togetherjoins时,与CDataProvider分页和/或排序发生了奇怪的冲突。没有特定的简单方法来描述这一点,但在CDataProviders中使用复杂查询时,我遇到了一些奇怪的问题,参数被丢弃,并发生了此错误。
    在Yii中解决这些问题的一个非常有用的方法是在配置文件中启用参数记录。在配置文件中将此添加到db数组:
'enableParamLogging'=>true,

并且确保CWebLogRoute路由已经在你的log节中设置好了,这将打印出给出错误的查询,以及它试图绑定的所有参数,非常有用!

llew8vvj

llew8vvj2#

您可能试图将参数绑定在单引号内,而不是让它为您工作。
比较:

Model::model()->findAll("t.description ilike '%:filter%'", array(':filter' => $filter));

其中:

Model::model()->findAll("t.description ilike :filter", array(':filter' => '%' . $filter . '%'));
yvfmudvl

yvfmudvl3#

对于我来说,这个错误的一个原因是当你处理一个动态的参数数组时,如果你取消设置任何参数,你需要在传入它们之前重新索引。这个错误的残酷部分是你的错误日志不显示索引,所以看起来一切都是正确的。

SELECT id WHERE x = ?, y = ?, z = ?

可能生成日志:无效的参数编号:未使用params(“x”,“y”,“z”)定义参数
这看起来不应该抛出错误,但如果索引类似于:

0 => x, 1 => y, 4 => z

它认为最后一个参数是未定义的,因为它要查找键2。

ffdz8vbo

ffdz8vbo4#

我在尝试执行以下操作时遇到此错误:

$stmt = $pdo->prepare("select name from mytable where id = :id");
$stmt->execute([
  'id' => $id,
  'unusedvar' => $foo, // This row causes the error.
]);

基本上,不能将数组中未使用的参数传递给execute(),数组中传递给execute()的每个值都必须在预准备语句中使用。
这也在docs
无法绑定超过指定数量的值;如果input_parameters中存在的键比PDO::prepare()中指定的SQL中存在的键多,则语句将失败并发出错误。

相关问题