PDOINSERTおよびUPDATEプリペアドステートメントをINSERTおよびONDUPLICATE KEY UPDATEに切り替えたいのですが、これは現在行っているよりもはるかに効率的だと思いますが、正しい構文を理解するのに問題があります。名前付きプレースホルダーとbindParamで使用します。
SOで同様の質問をいくつか見つけましたが、PDOを初めて使用するため、コードを基準にうまく適合させることができませんでした。これは私が試したものですが、機能しません(挿入も更新もしません):
try {
$stmt = $conn->prepare('INSERT INTO customer_info (user_id, fname, lname) VALUES(:user_id, :fname, :lname)'
'ON DUPLICATE KEY UPDATE customer_info SET fname= :fname,
lname= :lname
WHERE user_id = :user_id');
$stmt->bindParam(':user_id', $user_id);
$stmt->bindParam(':fname', $_POST['fname'], PDO::PARAM_STR);
$stmt->bindParam(':lname', $_POST['lname'], PDO::PARAM_STR);
$stmt->execute();
}
これは私のコードの簡略版です(いくつかのクエリがあり、各クエリには20〜50のフィールドがあります)。私は現在最初に更新していて、更新された行数が0より大きいかどうかを確認し、そうでない場合はInsertを実行しています。これらのクエリには、それぞれ独自のbindParamステートメントのセットがあります。
ON DUPLICATE KEY
構文が正しくありません。
$stmt = $conn->prepare('INSERT INTO customer_info (user_id, fname, lname) VALUES(:user_id, :fname, :lname)
ON DUPLICATE KEY UPDATE fname= :fname2, lname= :lname2');
$stmt->bindParam(':user_id', $user_id);
$stmt->bindParam(':fname', $_POST['fname'], PDO::PARAM_STR);
$stmt->bindParam(':lname', $_POST['lname'], PDO::PARAM_STR);
$stmt->bindParam(':fname2', $_POST['fname'], PDO::PARAM_STR);
$stmt->bindParam(':lname2', $_POST['lname'], PDO::PARAM_STR);
ON DUPLICATE KEY
句にテーブル名またはSET
を入れる必要はなく、WHERE
句も必要ありません(常に重複キーでレコードを更新します) )。
http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html を参照してください
また、PHP構文エラー:クエリを2つの文字列に分割しました。
更新:
複数のパラメーターをバインドするには:
function bindMultiple($stmt, $params, &$variable, $type) {
foreach ($params as $param) {
$stmt->bindParam($param, $variable, $type);
}
}
それからそれを呼んでください:
bindMultiple($stmt, array(':fname', ':fname2'), $_POST['fname'], PDO::PARAM_STR);
以下の私見は、これに再び遭遇する人にとって正しい答えです。
注:このステートメントは、user_idがテーブル内のKEYであることを前提としています。
声明は確かに間違っていましたが、受け入れられた答えは完全に正しくありませんでした。
同じ値を使用して挿入および更新する場合(異なる値で更新しない場合)、これは修正されたクエリの擬似コードです。
try {
//optional if your DB driver supports transactions
$conn->beginTransaction();
$stmt = $conn->prepare('INSERT INTO customer_info (user_id, fname, lname) ' .
'VALUES(:user_id, :fname, :lname)' .
'ON DUPLICATE KEY UPDATE fname=VALUES(fname), lname=VALUES(lname)');
$stmt->bindParam(':user_id', $user_id);
$stmt->bindParam(':fname', $_POST['fname'], PDO::PARAM_STR);
$stmt->bindParam(':lname', $_POST['lname'], PDO::PARAM_STR);
$stmt->execute();
//again optional if on MyIASM or DB that doesn't support transactions
$conn->commit();
} catch (PDOException $e) {
//optional as above:
$conn->rollback();
//handle your exception here $e->getMessage() or something
}