【问题标题】:PDO SELECT and UPDATE loopPDO 选择和更新循环
【发布时间】:2018-05-16 08:15:47
【问题描述】:

我对 foreach 和 while 之类的 php 循环非常不满意,所以我寻求帮助。

我需要循环这段代码:

$loser = $pdo->prepare("SELECT `user` FROM `contest` WHERE `winner`= '0'");
$loser->execute();

$balance = $pdo->prepare("SELECT `balance` FROM `users` WHERE `login` = '$loser'");
$balance->execute();

$new_balance = $balance + 100;

$back = $pdo->prepare("UPDATE `users` SET `balance`= '$new_balance' WHERE `login`= '$loser'");
$back->execute();

$returned = $pdo->prepare("UPDATE `contest` SET `returned`= '1' WHERE `login`= '$loser'");
$returned->execute();

我尝试了几件事并在这里寻找类似的问题,但不幸的是我无法提出解决方案。有人可以帮忙吗?

【问题讨论】:

  • 对你之后的哪种循环有帮助的一些解释。
  • 我需要的是逐行遍历表contest并为每一行执行此代码。
  • 你能在问题中添加表架构和一些数据吗?

标签: php pdo foreach while-loop


【解决方案1】:

我意识到下面的代码可能远远超出了要求,但它确实很好地利用了数据库的一些强大功能,并在 php 代码中保存了任何混乱的循环和杂散变量。

以下是使用虚构的数据库表和数据进行的部分测试。 在数据库中使用stored procedure,它本身使用cursor 来迭代初始记录集,然后执行更新计算。

mysql> describe balance;
+---------+------------------+------+-----+---------+----------------+
| Field   | Type             | Null | Key | Default | Extra          |
+---------+------------------+------+-----+---------+----------------+
| id      | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| balance | float unsigned   | NO   |     | 0       |                |
| login   | varchar(50)      | NO   | MUL | 0       |                |
+---------+------------------+------+-----+---------+----------------+

mysql> describe contest;
+----------+---------------------+------+-----+---------+----------------+
| Field    | Type                | Null | Key | Default | Extra          |
+----------+---------------------+------+-----+---------+----------------+
| id       | int(10) unsigned    | NO   | PRI | NULL    | auto_increment |
| returned | tinyint(3) unsigned | NO   | MUL | 0       |                |
| login    | varchar(50)         | NO   | MUL | 0       |                |
| winner   | int(10) unsigned    | NO   | MUL | 0       |                |
| user     | varchar(50)         | YES  |     | NULL    |                |
+----------+---------------------+------+-----+---------+----------------+

mysql> describe users;
+---------+------------------+------+-----+---------+----------------+
| Field   | Type             | Null | Key | Default | Extra          |
+---------+------------------+------+-----+---------+----------------+
| id      | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| balance | float            | YES  |     | NULL    |                |
| login   | varchar(50)      | YES  |     | NULL    |                |
+---------+------------------+------+-----+---------+----------------+






mysql> select * from balance;
+----+---------+-------+
| id | balance | login |
+----+---------+-------+
|  1 |       0 | rita  |
|  2 |       0 | sue   |
|  3 |       0 | bob   |
+----+---------+-------+

mysql> select * from contest;
+----+----------+-------+--------+------+
| id | returned | login | winner | user |
+----+----------+-------+--------+------+
|  1 |        0 | rita  |      0 | rita |
|  2 |        0 | sue   |      0 | sue  |
|  3 |        0 | bob   |      1 | bob  |
+----+----------+-------+--------+------+

mysql> select * from users;
+----+---------+-------+
| id | balance | login |
+----+---------+-------+
|  1 |       0 | bob   |
|  2 |       0 | rita  |
|  3 |       0 | sue   |
+----+---------+-------+


/* calling the stored procedure ~ this will be done in PHP */
mysql> call `spUpdateContest`(100);
+----------+
| result   |
+----------+
| finished |
+----------+
1 row in set (0.01 sec)




mysql> select * from users;
+----+---------+-------+
| id | balance | login |
+----+---------+-------+
|  1 |       0 | bob   |
|  2 |     100 | rita  |
|  3 |     100 | sue   |
+----+---------+-------+
3 rows in set (0.00 sec)




create definer=`root`@`localhost` procedure `spUpdateContest`(
    in `p_addition` int
)
language sql
not deterministic
contains sql
sql security definer
comment ''

proc:begin

    declare done int default false;
    declare _addition int default 0;
    declare _balance integer default 0;
    declare _loser varchar(50);
    declare _cursor cursor for select `user` from `contest` where `winner`= '0';

    declare continue handler for not found set done=true;

    set @_addition=cast( p_addition as unsigned );


    open _cursor;
    repeat
    fetch _cursor into _loser;


    if not done then

        select `balance` into @_balance from `users` where `login` = _loser;
        update `users` set `balance`= @_balance + @_addition where `login`= _loser;
        update `contest` set `returned`= '1' where `login` = _loser;

    end if;

    until done end repeat;
    close _cursor;

    set _balance=null;
    set _loser=null;
    set _addition=null;
    set done=null;

    select 'finished' as 'result';
end

在 PHP 中可以这样调用:

$sql='call `spUpdateContest`( 100 )';

【讨论】:

  • 非常感谢您的回答。
  • 希望大家能看懂stored procedure,可以为自己的数据库实现。
【解决方案2】:

谢谢大家。我找到了解决方案:

$stmt = $pdo->prepare('SELECT * from contest  WHERE winner=0');
$stmt -> execute();
while($row = $stmt->fetch()) {

$result_b = $pdo->prepare("SELECT `balance` FROM `users` WHERE `login` = '$row[user]'");

$result_b->execute();

$balance = $result_b->fetchColumn();

$new_balance = $balance + 100;

$back = $pdo->prepare("UPDATE `users` SET `balance` = '$new_balance' WHERE `login` = '$row[user]'");
$back->execute();

$returned = $pdo->prepare("UPDATE `contest` SET `returned` = '1'");
$returned->execute();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-30
    • 2015-08-13
    • 2021-02-04
    • 2017-02-03
    • 1970-01-01
    • 2018-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多