PDO prepared statements for INSERT and ON DUPLICATE KEY UPDATE with named placeholders

后端 未结 2 1854
礼貌的吻别
礼貌的吻别 2020-12-06 01:43

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

相关标签:
2条回答
  • 2020-12-06 02:15

    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
    }
    
    0 讨论(0)
  • 2020-12-06 02:26

    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);
    
    0 讨论(0)
提交回复
热议问题