編集:タイトルに「質問」という単語を含めることは許可されていません。Qマークは「疑問符」を意味します
編集2:ダミーの顧客レコードから個人の連絡先情報を削除する必要があることに気づきました
最近のプロジェクトのメンテナンスを減らすために、いくつかの基本的な機能を作ろうとしています。これらの中には、次の単純な関数があります。これにより、更新クエリを変更することなく、後日データベースに列を追加できます。
function update( $table, $fields ) {
global $db; // A slightly modified PDO object
if( count( $fields ) > 0 ) {
$query = "UPDATE `" . $table . "` SET ";
foreach( $customer as $key => $value ) {
$query .= "`" . $key . "` = ?, ";
}
$query = substr( $query, 0, -2 );
$query .= " WHERE `id` = " . $_REQUEST['id'];
$db->prepare( $query );
$db->execute( $fields );
} else { return true; }
}
この関数は、1つまたは2つのフィールドを渡したときに機能していましたが、さらに渡そうとした瞬間に失敗しました。$fields
受け取ったクエリ、値、エラーは次のとおりです。
クエリ:
string 'UPDATE `customers` SET `5v` = ?, `contactaddress` = ?, `contactaddress2` = ?, `contactcity` = ?, `contactemail` = ?, `contactname` = ?, `contactphone` = ?, `contactstate` = ?, `contactzip` = ?, `corrugated` = ?, `name` = ?, `permalok` = ?, `residential` = ?, `secureseam` = ?, `tax` = ? WHERE `id` = 1' (length=301)
$ fields:
array
'5v' => string '120' (length=3)
'contactaddress' => string '999 Street Dr' (length=13)
'contactaddress2' => string 'Apt 2' (length=7)
'contactcity' => string 'City' (length=9)
'contactemail' => string 'steven.abarnett@gmail.com' (length=25)
'contactname' => string 'Steven Barnett' (length=14)
'contactphone' => string '(555) 555-5555' (length=14)
'contactstate' => string 'KY' (length=2)
'contactzip' => string '55555' (length=5)
'corrugated' => string '90' (length=2)
'name' => string 'Steven's Metals' (length=15)
'permalok' => string '130' (length=3)
'residential' => string '100' (length=3)
'secureseam' => string '130' (length=3)
'tax' => string '6' (length=1)
エラー:
string 'Statement execution failed: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined' (length=96)
このエラーをグーグルで検索すると、疑問符のパラメーターではなく、名前付きパラメーターの問題のように聞こえます。なぜこのエラーが発生するのですか?
更新:
私はデバッグと実験を続け、エラーを追跡しました。失敗したのはステートメントの実行ではなく、後で結果をフェッチしようとしたことです。
変更したPDOオブジェクトでは、execute()
メソッド内に次のコードがあります。
// Load from database
try {
$this->stmt->execute( $args );
$this->lastid = $this->dbh->lastInsertId();
$this->data = $this->stmt->fetchAll();
} catch (PDOException $e) {
$this->error = 'Statement execution failed: ' . $e->getMessage();
return false;
}
echo
セクションの各行の間にステートメントを配置するtry{}
と、最初の2行は問題なく実行されますが、3行目は例外をスローしています。
電話をかけると、クエリが一般的なエラーで失敗する理由はありますPDOStatement::fetchAll()
か?
最終更新:
結局のところ、PDOとMysqlは6年間うまく機能していません。一般的な解決策は、を呼び出すたびにPDOStatementオブジェクトの設定を解除することのようですがPDOStatement::execute()
、これはうまくいきませんでした。この問題は、MySQLがレコードセット内のレコードを指すカーソルを一度に1つしか開くことができないという事実に起因しているため、別の提案された解決策は、ORPDOStatement::fetchAll()
の代わりにを使用PDOStatement::fetch()
してを呼び出すことPDOStatement::closeCusor()
です。繰り返しますが、これは私にはうまくいきませんでした。私の問題は、、、、およびクエリ中INSERT
にカーソルを作成するMySQLの特定のインストールに起因します(これらはすべてデータを返しません)。これは、nullデータを指しているため閉じることができません。UPDATE
DELETE
PDOStatement::fetchAll()
私の解決策は、データを返すクエリを実行しているときにのみ呼び出すことでした。queryhash
キャッシュ(PDOクラスに加えた大きな変更)で使用された変数がありfalse
、これらの3つのクエリタイプに設定されています(キャッシュを延期するのではなく、データベースにクエリを送信する必要があるため)。execute()
この変数をチェックfetchAll()
し、falseに設定されていない場合にのみ呼び出すように、関数を変更しただけです。