3

詳細

新しいライセンスまたは更新されたライセンスの有効期限が切れた場合に、単一の挿入を行っています。有効期限は、挿入日から2年間です。重複が検出された場合、有効期限が残りの有効期限に 2 年を加えた値になるようにエントリが更新されます。

重複に関しては、以下の例では、user_id =55 および licence=commercial を含む行が 1 つだけ存在する必要があります。

表: licence_expiry

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

user_id (int11)、ライセンス (varchan50)、有効期限 (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または、再度バインドする 4 番目のパラメーターを作成することもできます。

$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 で挿入を使用する別のステートメントを使用する場合は、このコードを試すことができます

$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 に答える