"参数号无效:未定义参数"插入数据

k t*_*e z 39 php mysql parameters yii

UPDATE

列出VALUES时我犯了一个小错误.我应该输入":username"而不是":alias".我想这个问题的答案可归功于任何想要它的人的免费统治吗?或者我删除这个问题?

原版的

我一直在使用Yii的活跃记录模式.现在,我的项目需要为一个小事务访问不同的数据库.我认为Yii的DAO对此有好处.但是,我收到了一个神秘的错误.

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));
}
Run Code Online (Sandbox Code Playgroud)

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

INSERT INTO users (username, password, ssn, surname, firstname, email
                   , city, country) 
VALUES(:alias, :password, :ssn, :surname, :firstname, :email, :city, :country);
Run Code Online (Sandbox Code Playgroud)

FYI $model->placeOfBirth应该是城市和县的价值观.这不是一个错字(我只是一件傻事).

tha*_*smt 92

只是为了提供答案 - 因为这个错误很常见 - 这里有几个原因:

1):parameter名称与错误绑定不匹配(拼写错误?).这就是这里发生的事情.他:alias在SQL语句中有约束力:username.因此,当尝试param绑定时,Yii/PDO :username在sql语句中找不到,这意味着它是"一个参数短"并且引发了错误.

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

3)使用together和时与CDataProvider分页和/或排序的奇怪冲突joins.没有特定的,简单的方法来表征这一点,但是当在CDataProviders中使用复杂查询时,我遇到了一些奇怪的问题,即参数被丢弃并且发生了这种错误.

在Yii中解决这些问题的一种非常有用的方法是在配置文件中启用参数记录.将其添加到db配置文件中的数组中:

'enableParamLogging'=>true,
Run Code Online (Sandbox Code Playgroud)

并确保CWebLogRoute在您的log部分中设置路线.这将打印出给出的查询和错误,以及它试图绑定的所有参数.超级有用!

  • 好帖子.我在我的实例中发现我在其中一个col名称之后有一个空格,这足以引发错误. (4认同)
  • 此处有效占位符字符的列表http://stackoverflow.com/questions/5809951/pdo-valid-characters-for-placeholders (2认同)

jtu*_*bre 6

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

SELECT id WHERE x = ?, y = ?, z = ?
Run Code Online (Sandbox Code Playgroud)

可能会产生日志:无效的参数号:参数未使用参数(“x”,“y”,“z”)定义

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

0 => x, 1 => y, 4 => z
Run Code Online (Sandbox Code Playgroud)

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

  • 添加到您的答案中,一个简单的 print_r 将显示索引,并且可以使用 array_values 进行修复,因为它将重新索引从 0 开始的数组 (2认同)

Lar*_*röm 6

当我尝试执行以下操作时出现此错误:

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

基本上,您不能将数组中未使用的参数传递给execute(). 传递给数组中的每个值都execute()必须在准备好的语句中使用。

这也在文档中指定:

不可能绑定比指定更多的值;如果 input_parameters 中存在的键多于 PDO::prepare() 中指定的 SQL 中的键,则该语句将失败并发出错误。


Ala*_*lms 5

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

相比:

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

和:

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