如何使用mysql在PDO中进行重复密钥更新?

如何使用mysql在PDO中进行重复密钥更新?,mysql,pdo,duplicates,Mysql,Pdo,Duplicates,详细信息 我正在为新的或更新的许可证的到期做一次插入。有效期为自插入日期起2年。 如果检测到重复,条目将被更新,以便到期日等于剩余到期日加上2年。 $sql = "INSERT INTO $table (user_id, licence, expiry) VALUES ( :user_id, :licence,

详细信息

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

$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();        
    }
关于副本,在下面的示例中,应该只有一行包含user_id=55和license=commercial

表格:许可证到期

--------------------------------------------------------
|   user_id   |   licence   |           expiry         |  
--------------------------------------------------------
|     55      |  commercial |     2013-07-04 05:13:48  |  
---------------------------------------------------------
用户id(int11)、许可证(varchan50)、到期日(日期时间)

我认为在mysql中您可以这样编写(请注意,我还没有检查代码在mysql中是否有效)

问题:如何使用PDO实现这一点?我已经写了一个大概的大纲,我认为我将使用什么,但我不确定在重复密钥更新时为的到期值写什么。

$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();        
    }
非常感谢您的帮助。

您可以使用MySQL的功能:

在语句中,可以使用子句中的
值(col\u name
函数引用语句部分的列值。换句话说,子句中的
值(col\u name
是指在没有出现重复键冲突的情况下插入的
col\u 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.

我知道你有下面的答案,但我有同样的问题,我的解决方案看起来非常不同,但它对我有效,所以如果你想在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);

这可能是一个愚蠢的问题,在重复的情况下,我是否可以获取现有的到期值,并使用重复密钥更新计算更新的到期时间?@moohoo:Ugh,我完全错过了原始问题中的这一点。是的,你可以-就像你最初提议的那样:
。。。更新到期=到期+间隔2年
。当然,这将在PDO上工作,就像在任何其他MySQL客户机上一样。