web-dev-qa-db-ja.com

「無効なパラメーター番号:パラメーターが定義されていませんでした」データの挿入

[〜#〜] update [〜#〜]

VALUESを一覧表示するときに、ちょっとした間違いを犯していました。 「:alias」ではなく、「:username」を入れるべきでした。この質問に対する答えは、それを望む人のための自由な統治だと思いますか?または、質問を削除しますか?

[〜#〜] original [〜#〜]

私はしばらくの間Yiiのアクティブなレコードパターンを使用しています。ここで、私のプロジェクトは1つの小さなトランザクションで別のデータベースにアクセスする必要があります。 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は、市と郡の両方の値になるはずです。それはタイプミスではありません(私がしなければならない愚かなことです)。

38
k to the z

答えを提供するために-このエラーは非常に一般的であるため-ここにいくつかの原因があります:

1)_:parameter_名が誤ってバインドと一致しません(タイプミス?)。これがここで起こったことです。 SQLステートメントに_:alias_がありますが、_:username_にバインドされています。そのため、paramバインディングが試行されたときに、Yii/PDOはsqlステートメントで_:username_を見つけることができませんでした。つまり、「1つのパラメーターが短い」ためエラーがスローされました。

2)パラメーターにbindValue()を追加することを完全に忘れます。これは、Yii _$critera_のような他の構成体で、配列またはパラメーター($criteria->params = array(':bind1'=>'test', ':bind2'=>'test))がある場合)で行う方が簡単です。

3)togetherおよびjoinsを使用する場合、CDataProviderのページネーションおよび/またはソートとの奇妙な競合。これを特定する特定の簡単な方法はありませんが、CDataProvidersで複雑なクエリを使用すると、パラメーターがドロップされ、このエラーが発生するという奇妙な問題がありました。

Yii)でこれらの問題をトラブルシューティングする1つの非常に便利な方法は、構成ファイルで パラメーターロギングを有効にする です。これを構成のdb配列に追加しますファイル:

_'enableParamLogging'=>true,
_

CWebLogRouteセクションにlogルートが設定されていることを確認してください。これにより、エラーを与えたクエリと、バインドしようとしたすべてのパラメータが出力されます。とても助かりました!

91
thaddeusmt

上記で説明されていないこのエラーの原因は、パラメーターの設定を解除した場合にパラメーターの動的配列を処理しているときに、パラメーターを渡す前にインデックスを再作成する必要があることです。すべてが正しいように見えるようにインデックスを表示します。例えば:

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

ログを生成する可能性があります:無効なパラメーター番号:パラメーターはparamsで定義されていません( "x"、 "y"、 "z")

これはエラーをスローすべきではないように見えますが、インデックスが次のようなものである場合:

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

キー2を探しているため、最後のパラメーターは未定義と見なされます。

4
jtubre

Paramを動作させるのではなく、単一引用符でパラメータをバインドしようとしているのかもしれません。

比較:

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

と:

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

私は次のようなことをしようとしたときにこのエラーが発生しました:

_$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よりも多くのキーが存在する場合、ステートメントは失敗し、エラーが発生します。

2
Lars Nyström