【发布时间】:2014-09-22 21:05:20
【问题描述】:
当我在最后一个选择中添加算术时,收到此查询的以下错误消息......这是一个非常简单的计算,所以不确定问题是什么:
alert.last_email is a utc timestamp (unsigned integer)
alerts.email_rate is value in minutes (unsigned integer)
这是一个消息队列...我试图将sends_in 设置为发送消息的秒数。
例如使用正常时间而不是时间戳...最后一封电子邮件是在晚上 7:00 发送的,费率为 15 分钟,因此它将在 7:15 发送。如果当前时间是 7:10,则发送时间为 5 分钟或 300 秒。
致命错误:已用尽允许的 33554432 字节内存大小(已尝试 在第 0 行的 Unknown 中分配 505364672 字节
$stmt = $db->prepare("
SELECT
users.username AS username,
computers.computer_name AS computer_name,
alerts.last_email AS last_email,
alerts_queue.alert_id AS alert_id,
alerts_queue.event_title AS event_title,
alerts_queue.event_target AS event_target,
alerts_queue.capture_timestamp AS capture_timestamp,
alerts.last_email + (alerts.email_rate * 60) - UNIX_TIMESTAMP() AS sends_in
FROM computers
INNER JOIN users
ON users.computer_id = computers.computer_id
INNER JOIN alerts
ON alerts.user_id = users.user_id
INNER JOIN alerts_queue
ON alerts_queue.user_id = alerts.user_id
WHERE computers.account_id = :cw_account_id AND computers.status = :cw_status
");
$binding = array(
'cw_account_id' => $_SESSION['user']['account_id'],
'cw_status' => 1
);
$stmt->execute($binding);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
更新:
计算未按预期工作:
TIMESTAMPDIFF(秒, UTC_TIMESTAMP(), FROM_UNIXTIME(UNIX_TIMESTAMP() + alerts.email_rate * 60)) AS send_in
用这个作为测试......差异应该是 900 秒,但它返回 -13500。
TIMESTAMPDIFF(秒, UTC_TIMESTAMP(), FROM_UNIXTIME(UNIX_TIMESTAMP() + 15 * 60)) AS发送_in
更新:
我的错误 - 这将返回正确的值:
TIMESTAMPDIFF(SECOND, NOW(), FROM_UNIXTIME(UNIX_TIMESTAMP() + 15 * 60)) AS发送_in
工作解决方案:
它看起来有点草率,但这是可行的。 TIMESTAMPDIFF 使用当前时区...我的 last_email 值是一个 unix 时间戳,这是 FROM_UNIXTIME 发挥作用的地方。因为last_email 是无符号整数,所以除非将其转换为有符号整数,否则算术将无法正常工作。我总是将时间戳设置为无符号的原因是因为永远不会有负数,但是在使用 MySQL 进行算术运算的情况下,这会导致问题。
TIMESTAMPDIFF(SECOND, NOW(), FROM_UNIXTIME(CONVERT(alerts.last_email,SIGNED) + alerts.email_rate * 60)) AS发送_in
【问题讨论】:
-
这不是 mysql 错误。您可能返回的数据行过多,导致内存超载。
-
在这个测试中,只有两行数据...在没有涉及数学的最后一个选择的情况下工作得很好。
-
你试过使用 MySQL 的内置函数吗?
TIMESTAMPDIFF(SECOND, FROM_UNIXTIME(alerts.last_email + alerts.email_rate * 60), NOW()) AS sends_in或类似的?理想情况下,时间将存储为 DATETIME 而不是 INT... -
@miken32 - 虽然我需要颠倒值的顺序,但这很有效。老实说,我不知道这存在,但仍然好奇为什么其他方法不起作用。此外,NOW() 返回当前时区...我需要 UTC 时间。
-
@miken32 - 谢谢...上面有一个可行的解决方案,部分满足您的建议。