如何更新除最后一行之外的所有行?

时间:2016-07-13 18:41:17

标签: php mysql sql pdo

这是我的剧本:

try{

    $dbh_conn->beginTransaction();

    $user_id = $_POST['iuser_id'];
    $token   = hash('sha512', bin2hex(openssl_random_pseudo_bytes(16)).$user_id);

    $stm = $dbh_conn
    ->prepare("INSERT INTO resend_pass(user_id, token, date_time)
                SELECT ?, ?, unix_timestamp()
                FROM dual
                WHERE NOT EXISTS( SELECT count(*) AS num_week,
                                         COALESCE(sum(date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1  day))),0)  as num_day,
                                         COALESCE(sum(date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1  hour))),0) as num_hour,
                                         COALESCE(sum(date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 minute))),0) as num_1min
                                    FROM resend_pass
                                   WHERE user_id   = ?  
                                     AND date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 WEEK))
                                  HAVING num_week > 11 OR num_day > 5 OR num_hour > 3 OR num_1min > 0 );");
    $stm->execute(array($user_id, $token, $user_id));

    // no row inserted (either there is lots of reuqests or duplicate token (this one has very low possibility))
    if ( !$stm->rowCount() ) { throw new Exception('something is wrong'); }

    $stmt = $dbh_conn->prepare("UPDATE resend_pass SET active = 0 WHERE user_id = ? AND {all rows except the last one}");
    $stmt->execute($user_id);

    $dbh_conn->commit();

    /* sending $token for that email  here  */

    $_SESSION["TopMSG"] = "<div class='msg_success'>
                            ایمیل با موفقیت ارسال شد 
                            <span>
                            - جهت انتخاب رمز عبور جدید
                            </span>
                            </div>";
    header('location: ../login');
    exit;

} catch(Exception $e) {

    $dbh_conn->rollBack();

    $_SESSION["TopMSG"] = "<div class='msg_success'>$e</div>";
    header('location: ../login');
    exit;

}

请关注这一行:

$stmt = $dbh_conn->prepare("UPDATE resend_pass SET active = 0 WHERE user_id = ? AND {all rows except the last one}");

如何设置除刚刚插入的最后一行以外的所有行?

5 个答案:

答案 0 :(得分:0)

http://php.net/manual/en/pdo.lastinsertid.php

您可以获取最后插入的ID并在where子句中使用它。

$lastId = $dbh_conn->lastInsertId();
$stmt = $dbh_conn->prepare("UPDATE resend_pass SET active = 0 WHERE user_id = ? AND [whatever column is used for resend_pass id] <> ?");
$stmt->execute(array($user_id, $lastId));

答案 1 :(得分:0)

如果表中有自动增量列,则可以获取最后一个插入行的id,并将其添加到第二个查询的WHERE子句中。

答案 2 :(得分:0)

可能更容易移动以下声明:

$stmt = $dbh_conn->prepare("UPDATE resend_pass SET active = 0 WHERE user_id = ?");

在Insert one之上,因此无需更改新记录。并且不再需要AND条件

此致

答案 3 :(得分:0)

我不知道你怎么想“最后”。它可能是最大日期,可能是最小日期,可能是最大ID,也可能是最小ID。在下面的示例中,我使用min date_time字段。将子查询替换为您需要的内容

 UPDATE resend_pass 
    SET active = 0 
  WHERE user_id = ? AND date_time <> 
   (select min(date_time) 
      from resend_pass
    where user_id = ?) 

答案 4 :(得分:0)

如果我能很好地理解你的问题,那么我认为你可以使用你的PDO连接得到最后插入行的id

$lastId = $dbh_conn->lastInsertId();

然后在sql查询中使用$lastId的值。