PDO制备了命名占位符insert和重复键UPDATE语句(PDO prepared stateme

2019-07-17 17:22发布

我想切换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语句。

Answer 1:

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);      

你不需要把表名或SETON 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);


Answer 2:

下面恕我直言,是任何人碰到这个再来正确的答案。
注意:这种说法假定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