簡體   English   中英

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

[英]How can I update all rows except the last one?

這是我的腳本:

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}");

我怎樣才能知道它設置了除了最后插入的所有行之外的所有行?

http://php.net/manual/zh/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));

如果表中有一個自動遞增的列,則可以獲取最后插入的行的ID,並將其添加到第二個查詢的WHERE子句中。

也許移動以下語句會更容易:

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

在“插入”上方,因此無需更改新記錄。 並且不再需要AND條件

問候

我不知道你如何看待“最后”。 它可能是最大日期,可能是最小日期,可能是最大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 = ?) 

如果我很好地理解了您的問題,那么我認為您可以使用PDO連接獲取最后插入的行的ID。

$lastId = $dbh_conn->lastInsertId();

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM