SQLSTATE[HY093]:参数号无效:参数未定义

发布于 2024-11-05 11:10:00 字数 1717 浏览 0 评论 0原文

我使用 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));
}

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

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

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

I've been using Yii's active record pattern for a while. Now, my project needs to access a different database for one small transaction. I thought the Yii's DAO would be good for this. However, I'm getting a cryptic error.

CDbCommand failed to execute the SQL statement: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined

Here is my code:

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));
}

This constructs the following query (as seen on the application log):

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

FYI $model->placeOfBirth is supposed to be in both city and county values. That's not a typo (just a silly thing I have to do).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

橘味果▽酱 2024-11-12 11:10:00

只是为了提供一个答案 - 因为此错误非常常见 - 以下是一些原因:

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

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

  3. 另一个可能的原因是占位符名称中的字符无效

  4. 与 CDataProvider 分页发生奇怪的冲突和/或使用togetherjoins时进行排序。没有具体、简单的方法来描述这一点,但是当在 CDataProviders 中使用复杂查询时,我遇到了参数丢失和发生此错误的奇怪问题。

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

'enableParamLogging'=>true,

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

Just to provide an answer - because this error is pretty common - here are a few causes:

  1. The :parameter name does not match the bind by mistake (typo?). This is what happened here. They have :alias in the SQL statement, but bound :username. So when the param binding was attempted, Yii/PDO could not find :username in the sql statement, meaning it was "one parameter short" and threw an error.

  2. Completely forgetting to add the bindValue() for a parameter. This is easier to do in Yii other constructs like $critera, where you have an array or params ($criteria->params = array(':bind1'=>'test', ':bind2'=>'test)).

  3. another possible reason is invalid character in the placeholder name

  4. Weird conflicts with CDataProvider Pagination and/or Sorting when using together and joins. There is no specific, easy way to characterize this, but when using complex queries in CDataProviders I have had weird issues with parameters getting dropped and this error occurring.

One very helpful way to troubleshoot these issues in Yii is to enable parameter logging in your config file. Add this to your db array in your config file:

'enableParamLogging'=>true,

And make sure the CWebLogRoute route is set up in your log section. This will print out the query that gave and error, and all of the parameters it was attempting to bind. Super helpful!

水溶 2024-11-12 11:10:00

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

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

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

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

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

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

A cause of this error for me not covered above is when you're dealing with a dynamic array of parameters if you unset any params, you need to reindex before passing them in. The brutal part of this is that your error log doesn't show indexes so it looks like everything is right. Eg:

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

Might produce the Log: Invalid parameter number: parameter was not defined with params ("x","y","z")

This looks like it shouldn't be throwing an error, but if the indexes are something like:

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

It considers the last parameter undefined because it's looking for key 2.

漫漫岁月 2024-11-12 11:10:00

当尝试执行以下操作时,我收到此错误:

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

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

文档中也对此进行了指定:

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

I got this error when trying to do something like:

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

Basically, you can't have unused parameters in the array passed to execute(). Every value in the array passed to execute() must be used in your prepared statement.

This is also specified in the docs:

Binding more values than specified is not possible; if more keys exist in input_parameters than in the SQL specified in the PDO::prepare(), then the statement will fail and an error is emitted.

空城仅有旧梦在 2024-11-12 11:10:00

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

比较:

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

与:

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

May be you are trying to bind a param within single quotes instead of letting it does the work for you.

Compare:

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

With:

Model::model()->findAll("t.description ilike :filter", array(':filter' => '%' . $filter . '%'));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文