Php &引用;无效参数编号:未定义参数";插入数据

Php &引用;无效参数编号:未定义参数";插入数据,php,mysql,yii,Php,Mysql,Yii,我已经使用Yii的活动记录模式有一段时间了。现在,我的项目需要为一个小事务访问不同的数据库。我以为彝族刀会很适合这个。然而,我得到了一个神秘的错误 CDbCommand无法执行SQL语句:SQLSTATE[HY093]:参数编号无效:未定义参数 这是我的密码: public function actionConfirmation { $model_person = new TempPerson(); $model = $model_person->find('alias=

我已经使用Yii的活动记录模式有一段时间了。现在,我的项目需要为一个小事务访问不同的数据库。我以为彝族刀会很适合这个。然而,我得到了一个神秘的错误

CDbCommand无法执行SQL语句:SQLSTATE[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));
}
这将构造以下查询(如应用程序日志所示):


FYI
$model->placeOfBirth
应同时包含城市值和县值。这不是打字错误(我必须做一件愚蠢的事)。

只是为了提供一个答案——因为这个错误很常见——以下是一些原因:

1)
:参数
名称错误地与绑定不匹配(键入?)。这就是这里发生的事情。他在SQL语句中有
:alias
,但绑定了
:username
。因此,当尝试param绑定时,Yii/PDO在sql语句中找不到
:username
,这意味着它“短了一个参数”,并抛出了一个错误

2) 完全忘记为参数添加
bindValue()
。这在Yii其他构造(如
$critera
)中更容易实现,其中有一个数组或参数(
$criteria->params=array(':bind1'=>'test',':bind2'=>'test)

3) 当同时使用
连接时,CDATA提供程序分页和/或排序会发生奇怪的冲突。没有具体的、简单的方法来描述这一点,但是在CDATA提供者中使用复杂查询时,我遇到了一些奇怪的问题,参数被删除,并且出现了这个错误

在Yii中解决这些问题的一个非常有用的方法是在您的配置文件中。将其添加到配置文件中的
db
数组中:

'enableParamLogging'=>true,

并确保在
log
部分中设置了
CWebLogRoute
路由。这将打印出给出和错误的查询,以及它试图绑定的所有参数。非常有帮助

可能是您试图在单引号内绑定一个参数,而不是让它为您工作

比较:

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


对我来说,上面没有提到的这个错误的一个原因是,当你处理一个参数的动态数组时,如果你取消设置任何参数,你需要在传递它们之前重新建立索引。这其中最残酷的部分是错误日志没有显示索引,所以看起来一切正常。例如:

SELECT id WHERE x = ?, y = ?, z = ?
可能会生成日志:参数编号无效:未使用参数(“x”、“y”、“z”)定义参数

这看起来不应该抛出错误,但如果索引类似:

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

它认为最后一个参数未定义,因为它正在查找键2。

我在尝试执行以下操作时出错:

0 => x, 1 => y, 4 => z
$stmt = $pdo->prepare("select name from mytable where id = :id");
$stmt->execute([
  'id' => $id,
  'unusedvar' => $foo, // This row causes the error.
]);
基本上,数组中不能有未使用的参数传递给
execute()
。传递给
execute()
的数组中的每个值都必须在准备好的语句中使用

以下文件中也规定了这一点:

绑定的值不能超过指定值;如果输入_参数中存在的键比PDO::prepare()中指定的SQL中的键多,则该语句将失败并发出错误


好帖子。在我的实例中,我发现我的一个列名称后面有一个空格,这足以引发错误。我的有效占位符字符列表在bind调用中的一个列名称后面也有一个空格,很难发现的人在你的答案中添加一个简单的打印将显示索引,并且可以用数组值修复,因为它将从0开始重新索引数组