PDO SELECT和UPDATE循环

时间:2017-12-02 10:05:24

标签: php pdo foreach while-loop

对于像foreach这样的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();

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

2 个答案:

答案 0 :(得分:0)

我意识到下面的代码可能比需要的更多,但它确实充分利用了数据库的一些强大功能,并在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 )';

答案 1 :(得分:0)

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

$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();
}