3

细节

我正在为新的或更新的许可证到期做一次插入。有效期为自插入之日起 2 年。如果检测到重复,则将更新条目,使到期时间等于剩余到期时间加上 2 年。

关于重复项,在下面的示例中,应该只有一行包含 user_id =55 和 licence=commercial。

表: licence_expiry

--------------------------------------------------------
|   user_id   |   licence   |           expiry         |  
--------------------------------------------------------
|     55      |  commercial |     2013-07-04 05:13:48  |  
---------------------------------------------------------

user_id (int11), license (varchan50), expiry (DATETIME)

我认为在 mysql 中你会这样写(请注意,我没有检查代码是否在 mysql 中工作。)

INSERT INTO `licence_expiry`
(`user_id`, `licence`, `expiry`)
VALUES
(55, commercial, NOW()+ INTERVAL 2 YEAR)
ON DUPLICATE KEY UPDATE
`expiry` = `expiry` + INTERVAL 2 YEAR

问题:如何使用 PDO 做到这一点?我已经写了一个我认为我将使用的粗略大纲,但我不确定要为ON DUPLICATE KEY UPDATE 的到期值写什么。

$sql = "INSERT INTO $table (user_id, licence, expiry)
                        VALUES (
                        :user_id,  
                        :licence,
                        :expiry)
    ON DUPLICATE KEY UPDATE expiry = Something"; 


try {
    $dbh = new PDO('login info here');
    $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
    $stmt = $dbh->prepare($sql);
    $stmt->bindParam(':user_id', $userID, PDO::PARAM_INT);     
    $stmt->bindParam(':licence',$licence, PDO::PARAM_STR);
    $stmt->bindParam(':expiry',$expiry, PDO::PARAM_STR);                            
    $stmt->execute();
    //$stmt->closeCursor(); //use this instead of $dbh = null   if you will continue with another DB function
    $dbh = null; 
    }

    catch(PDOException $e)
    {
    $error=$e->getMessage();        
    }

任何帮助深表感谢。

4

2 回答 2

9

您可以使用 MySQL 的VALUES()功能:

INSERT ... ON DUPLICATE KEY UPDATE语句中,您可以使用子句中的函数来引用语句部分中的列值。换句话说,在子句中是指将被插入的值,没有发生重复键冲突。VALUES(col_name)UPDATEINSERTVALUES(col_name)UPDATEcol_name

因此,在您的情况下:

ON DUPLICATE KEY UPDATE expiry = VALUES(expiry)

或者,您可以创建$expiry再次绑定的第四个参数:

$sql = "INSERT INTO $table (user_id, licence, expiry)
                        VALUES (
                        :user_id,
                        :licence,
                        :expiry)
    ON DUPLICATE KEY UPDATE expiry = :another";


try {
    $dbh = new PDO('login info here');
    $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
    $stmt = $dbh->prepare($sql);
    $stmt->bindParam(':user_id', $userID , PDO::PARAM_INT);
    $stmt->bindParam(':licence', $licence, PDO::PARAM_STR);
    $stmt->bindParam(':expiry' , $expiry , PDO::PARAM_STR);
    $stmt->bindParam(':another', $expiry , PDO::PARAM_STR);
    $stmt->execute();
    // etc.
于 2012-07-09T06:38:24.727 回答
-1

我知道你在下面有答案,但我有同样的问题,我的解决方案看起来完全不同,但它适用于我,所以如果你想使用不同的语句在 mysql 中使用 insert 并显式绑定值到列,你可以试试这个代码

$sql = "
   INSERT INTO 
      $table 
   SET
      user_id = :user_id,
      licence = :licence,
      expiry  = :expiry
   ON DUPLICATE KEY UPDATE 
      expiry = :expiry
";

$dbh = new PDO('login info here');
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$stmt = $dbh->prepare($sql);
$stmt->bindValue('user_id', $userID , PDO::PARAM_INT);
$stmt->bindValue('licence', $licence, PDO::PARAM_STR);
$stmt->bindValue('expiry' , $expiry , PDO::PARAM_STR);
于 2013-02-23T08:57:17.993 回答