在mysql PDO中更新后选择行

Posted

技术标签:

【中文标题】在mysql PDO中更新后选择行【英文标题】:select row after update in mysql PDO 【发布时间】:2018-12-30 14:42:51 【问题描述】:

如何在使用PDOphp 的一次查询中更新后选择一行?

像这样:

function giftUpdate($username,$id,$date,$conn)
$update = $conn->prepare("UPDATE gifts SET used = 1 , user = :user , date = :date WHERE id = :id");
$update->bindParam("id" , $id );
$update->bindParam("date" , $date );
$update->bindParam("user" , $username );
$update->execute();
return $update ? true : false;

function giftGet($username,$currnetTime,$conn) 
$statment = $conn->prepare("SELECT * FROM gifts WHERE used = 0 ORDER BY `id` ASC");
$statment->execute();
$gift = $statment->fetch(PDO::FETCH_OBJ);
if($gift)
    $voucher = $gift->code;
    $voucherid = $gift->id;
    $vouchertype = $gift->type;
    $voucherkey = $gift->keys;

    if($voucher)
       $giftUpdate = giftUpdate($username,$voucherid,$currnetTime,$conn);
       if($giftUpdate)
        useUpdate($username , $conn);
       
    


usleep(50000);
return $gift ? $gift : false;

更新后我需要选择同一行发送给用户。

(我是一张包含 1000 行和列“已使用”的凭证列表的表,默认情况下为 0,并且根据用户请求,我需要在一个查询中更新此行以使用 1 并选择此行。)

我在这个功能中的问题是一些用户会收到重复的代金券并且一个代码被分配给几个用户。

伙计们...对于这种情况是否可以使用交易方法?或者您是否建议使用事务?

已编辑:

我最终更改了下面的代码,但我仍然在线:

从使用的礼物中选择 id = 0 ORDER BY id ASC limit 1 FOR UPDATE)");

但是当我从数据库中输入一个 id 而不是这段代码时,它就可以工作了!

function giftGet($username, $currnetTime, $conn)

$uniqid = uniqid('vouchers_');
$update = $conn->prepare("UPDATE gifts SET used = 1, uniqueid =:uniqueid , user = :user , date = :date WHERE id = (
                          SELECT id FROM gifts WHERE used = 0 ORDER BY `id` ASC limit 1 FOR UPDATE)");
$update->bindParam("date", $currnetTime);
$update->bindParam("uniqueid", $uniqid);
$update->bindParam("user", $username);
$update->execute();
$updaterowCount = $update->rowCount();
if ($updaterowCount)
    
    $statment = $conn->prepare("SELECT * FROM gifts WHERE uniqueid = :uniqueid ORDER BY `id` ASC");
    $statment->bindParam("uniqueid", $uniqid);
    $statment->execute();
    $gift = $statment->fetch(PDO::FETCH_OBJ);
    $voucherid = $gift->id;
    if ($gift)
        
        useUpdate($username, $voucherid, $conn);
        
    

return $gift ? $gift : false;

【问题讨论】:

更新后为什么要选择该行?如果您想确保它已更新,您可以使用$statement->rowCount() 查看您的记录是否已更新。 我是一张用于凭证列表的表,其中 1000 行和列“已使用”默认为 0,并且根据用户请求,我需要在一个查询中更新此行以使用 1 并选择此行。 如何确保您分发的代金券以前没有使用过? "UPDATE gifts SET used = 1 , user = :user , date = :date WHERE id = :id AND used = 0" - 之后您可以通过rowCount() 确认凭证是否已成功分配。 伙计们...对于这种情况是否可以使用事务方法?或者您是否建议使用事务? 【参考方案1】:

我会改变表gifs并添加一个列uniqueid(varchar)。

然后使用

$uniqid = uniqid('vouchers_');

并重写你的更新

"UPDATE gifts SET used = 1, uniqueid =:UNIQUEID , user = :user , date = :date WHERE id = (
SELECT id FROM gifts WHERE used = 0 ORDER BY `id` ASC limit 1 FOR UPDATE)";

现在您可以通过 uniqueid 来识别更新的记录。 在您的代码中,选择和更新之间存在时间间隔。 2个或更多用户可以同时开始选择,在更新之前收到相同的凭证使用= 1

【讨论】:

感谢您的回复,您对这个时间间隔有何建议。 首先用我的更新调用 giftUpdate(...),返回 $uniqid 并用 SELECT * FROM gift WHERE uniqueid =:UNIQUEID 调用 giftGet($uniqueid,...) 你认为使用“事务”不是更适合这个吗? 事务不会改变 select 语句的行为,在您的情况下我看不到任何好处

以上是关于在mysql PDO中更新后选择行的主要内容,如果未能解决你的问题,请参考以下文章

如何在 mysql PDO 选择查询中仅从时间戳中选择时间?

带有 PDO 连接的 MySQL SET

使用 PDO 选择 MYSQL 中的 PHP 变量 [重复]

更新选择列表而不刷新 [PDO/PHP/AJAX]

PDO和MySQLi , MySQL区别与选择?

MySQL更新,跳过PDO的空白字段