【问题标题】:"Invalid parameter number: parameter was not defined" Inserting data“无效参数编号:未定义参数” 插入数据
【发布时间】:2011-08-17 23:29:21
【问题描述】:

我使用 Yii 的主动记录模式已经有一段时间了。现在,我的项目需要为一笔小交易访问不同的数据库。我认为 Yii 的 DAO 会对此有好处。但是,我遇到了一个神秘的错误。

CDbCommand 执行 SQL 语句失败:SQLSTATE[HY093]: Invalid parameter number: parameter was not defined

这是我的代码:

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 应该是城市和县的值。这不是错字(只是我必须做的一件愚蠢的事情)。

【问题讨论】:

    标签: php mysql yii


    【解决方案1】:

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

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

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

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

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

    'enableParamLogging'=>true,
    

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

    【讨论】:

    • 好帖子。我在我的实例中发现,在其中一个 col 名称之后有一个空格,这足以引发错误。
    • 我的也是绑定调用中一个列名后面的空格,很难发现
    【解决方案2】:

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

    比较:

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

    与:

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

    【讨论】:

      【解决方案3】:

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

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

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

      这看起来不应该抛出错误,但如果索引是这样的:

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

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

      【讨论】:

      • 在您的答案中添加一个简单的 print_r 将显示索引并且可以使用 array_values 修复,因为它将重新索引从 0 开始的数组
      【解决方案4】:

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

      $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 中的键,则语句将失败并发出错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-13
        相关资源
        最近更新 更多