[〜#〜] 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
は、市と郡の両方の値になるはずです。それはタイプミスではありません(私がしなければならない愚かなことです)。
答えを提供するために-このエラーは非常に一般的であるため-ここにいくつかの原因があります:
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
ルートが設定されていることを確認してください。これにより、エラーを与えたクエリと、バインドしようとしたすべてのパラメータが出力されます。とても助かりました!
上記で説明されていないこのエラーの原因は、パラメーターの設定を解除した場合にパラメーターの動的配列を処理しているときに、パラメーターを渡す前にインデックスを再作成する必要があることです。すべてが正しいように見えるようにインデックスを表示します。例えば:
SELECT id WHERE x = ?, y = ?, z = ?
ログを生成する可能性があります:無効なパラメーター番号:パラメーターはparamsで定義されていません( "x"、 "y"、 "z")
これはエラーをスローすべきではないように見えますが、インデックスが次のようなものである場合:
0 => x, 1 => y, 4 => z
キー2を探しているため、最後のパラメーターは未定義と見なされます。
Paramを動作させるのではなく、単一引用符でパラメータをバインドしようとしているのかもしれません。
比較:
Model::model()->findAll("t.description ilike '%:filter%'", array(':filter' => $filter));
と:
Model::model()->findAll("t.description ilike :filter", array(':filter' => '%' . $filter . '%'));
私は次のようなことをしようとしたときにこのエラーが発生しました:
_$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よりも多くのキーが存在する場合、ステートメントは失敗し、エラーが発生します。