【问题标题】:Cron updating MySQLcron 更新 MySQL
【发布时间】:2017-03-07 07:00:18
【问题描述】:

我正在努力使用 CRON 更新 mysql 条目的代码。也许我只是看不出我做错了什么,但是maaan..我的头已经因为过度思考而受伤了。

*此代码应更新为每个用户显示回合的表格。我希望它为每个用户每 10 分钟添加一轮。

这是代码,每 10 分钟执行一次:

$conn = mysql_connect($dbhost, $dbuser, $dbpass);
mysql_select_db('universe_domination');
$sql = mysql_query("SELECT * FROM rounds");
foreach (mysql_fetch_array($sql) as $row) {
    $id = $row['id'];
    $free = $row['free'];
    $saved = $row['saved'];
    $lost = $row['lost'];
    if ($free < 200) {
        $roundSql = "UPDATE rounds SET free = free + 1 WHERE id = " . $id;
    } elseif ($free == 200 && $saved < 300) {
        $roundSql = "UPDATE rounds SET saved = saved + 1 WHERE id = " . $id;
    } elseif ($free == 200 && $saved == 300) {
        $roundSql = "UPDATE rounds SET lost = lost + 1 WHERE id = " . $id;
    }
    mysql_query($roundSql);
}

问题是,现在我有 4 个条目。

id  free  saved    lost
1    2      300   19568
2    200    250   19568
3    6      300   19568
4    7      300   19568

但更新后是这样的:

id  free  saved    lost
1    6      300   19568
2    200    250   19568
3    6      300   19568
4    9      300   19568

有人能告诉我这段代码有什么问题吗?我相信这是一些初学者的错误,但我找不到问题所在

**到目前为止,它编辑它有点错误...一行添加 4 个回合,第三个没有,第四个添加 2 个回合

****使用这个后仍然没有运气:

$conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
    $sql = "UPDATE rounds SET free = free + (CASE WHEN free < 200 THEN 1 ELSE 0 END),
            SET saved = saved + (CASE WHEN saved < 300 THEN 1 ELSE 0 END),
            SET lost = lost + (CASE WHEN free = 200 AND saved = 300 THEN 1 ELSE 0 END)";
    $updateRound = $conn->prepare($sql);
    $updateRound->execute();

--table 根本没有更新

【问题讨论】:

  • 为什么你甚至需要在 PHP 中这样做?您可以使用一条语句完全在 MySQL 中执行此查询。
  • 请先阅读How to Ask。你完全忽略了告诉我们你的代码应该做什么,以及你得到的结果是什么原因是错误的。
  • 我无法使用 MySQL,因为我的托管服务提供商不允许我使用触发器
  • @SLUNlCKO 我的意思是,无论您如何调用查询,您都可以在一个查询中完成所有这些操作。您现在执行此操作的方式(选择所有行,使用 PHP 分析数据,然后运行一堆查询来更新数据)是脆弱的,如果表有并发更新,则会中断。您可以简单地执行一条 SQL 语句(通过 PHP)并完成它。
  • @cdhowie 的意思类似于:UPDATE rounds SET free = case when free &lt; 200 then free + 1 else free end, saved = case when ..... where id = ....

标签: php mysql cron


【解决方案1】:

$roundSql 正在运行,即使所有 if/elseif 都失败了。结果是,根据数据,您可能有一个查询 - 为特定的 id 递增 free - 运行多次。有几种方法可以解决这个问题,包括:

1 - 在 if/elseif 的末尾有一个 else 以进行查询 - 即使它是一个空 MySQL 语句 - 当所有其他选项都失败时。

2 - 在 if 语句之前初始化 $roundSql。查询前先查看是否为空,不为空才进行查询。

作为调试工具,添加一些打印语句以查看正在运行的查询。

【讨论】:

    【解决方案2】:

    考虑在单个查询中完成所有这些操作,这样会更可靠(尤其是并发表访问)、更容易推理并且执行速度更快:

    $conn = mysql_connect($dbhost, $dbuser, $dbpass);
    mysql_select_db('universe_domination');
    
    mysql_query(<<<SQL
    UPDATE rounds
    SET free = free + (CASE WHEN free < 200 THEN 1 ELSE 0 END),
        saved = saved + (CASE WHEN free = 200 AND saved < 300 THEN 1 ELSE 0 END),
        lost = lost + (CASE WHEN free = 200 AND saved = 300 THEN 1 ELSE 0 END);
    SQL
    );
    

    附带说明,mysql_* 函数在 PHP 5.5 中已弃用,它们存在一些严重的 SQL 注入漏洞问题。请考虑改用 PDO 和准备好的语句。

    【讨论】:

    • 将您的解决方案与 mysqli 或 PDO 一起使用不起作用.. 表根本没有更新
    • SOLVED 首先我注意到我的托管服务提供商为 MySQL 使用了不同的端口,因此如果不定义端口(显然)它就无法工作。而且您的解决方案是错误的,因为它对每一列都使用 SET
    • 我的错,你是对的;我已经删除了额外的SETs,它现在应该可以工作了。
    猜你喜欢
    • 2013-08-04
    • 2020-09-04
    • 2021-02-21
    • 2019-02-26
    • 2017-10-02
    • 1970-01-01
    • 2018-04-18
    • 2013-06-20
    • 2018-06-20
    相关资源
    最近更新 更多