I\'d like to switch PDO INSERT and UPDATE prepared statements to INSERT and ON DUPLICATE KEY UPDATE since I think it\'ll be a lot more efficient than what I\'m currently doi
IMHO below is the right answer for anyone coming across this again.
Note: this statement assumes user_id is a KEY in the table.
The STATEMENT indeed was wrong, but the accepted answer was not completely correct.
If you're inserting and updating using the same values (and not updating with different values), this is the query pseudo-code corrected:
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
}
Your ON DUPLICATE KEY
syntax is not correct.
$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);
You don't need to put the table name or SET
in the ON DUPLICATE KEY
clause, and you don't need a WHERE
clause (it always updates the record with the duplicate key).
See http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html
You also had a PHP syntax error: you split the query up into two strings.
UPDATE:
To bind multiple parameters:
function bindMultiple($stmt, $params, &$variable, $type) {
foreach ($params as $param) {
$stmt->bindParam($param, $variable, $type);
}
}
Then call it:
bindMultiple($stmt, array(':fname', ':fname2'), $_POST['fname'], PDO::PARAM_STR);