我想切换PDO INSERT和UPDATE已准备语句insert和重复键UPDATE,因为我认为这将是一个很多比我目前在做什么更有效,但我无法正确的语法搞清楚,以与命名占位符和bindParam使用。
我发现有这么几种类似的问题,但我是新来的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,如果没有的话运行插入,而且每个查询有它自己的一套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);
你不需要把表名或SET
中ON DUPLICATE KEY
子句,你不需要一个WHERE
子句(它总是更新具有重复键的记录)。
见http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html
你也有一个PHP语法错误:您将查询分成两个字符串。
更新:
要绑定多个参数:
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是在表中的关键。
该声明的确是错了,但接受的答案是不完全正确的。
如果要插入,并使用相同的值更新(而不是与不同的值更新),这是纠正查询伪代码:
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
}
文章来源: PDO prepared statements for INSERT and ON DUPLICATE KEY UPDATE with named placeholders