Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php mysql select语句中的算术-内存大小错误_Php_Mysql_Pdo - Fatal编程技术网

Php mysql select语句中的算术-内存大小错误

Php mysql select语句中的算术-内存大小错误,php,mysql,pdo,Php,Mysql,Pdo,在上次选择中添加算术时收到此查询的以下错误消息。。。这是一个非常简单的计算,因此不确定问题是什么: alert.last_email is a utc timestamp (unsigned integer) alerts.email_rate is value in minutes (unsigned integer) 这是一个消息队列。。。我试图将sends\u in设置为发送消息的秒数 例如,使用正常时间而不是时间戳。。。最后一封邮件发送时间为晚上7:00,费率为15分钟,因此将在7:1

在上次选择中添加算术时收到此查询的以下错误消息。。。这是一个非常简单的计算,因此不确定问题是什么:

alert.last_email is a utc timestamp (unsigned integer)
alerts.email_rate is value in minutes (unsigned integer)
这是一个消息队列。。。我试图将
sends\u in
设置为发送消息的秒数

例如,使用正常时间而不是时间戳。。。最后一封邮件发送时间为晚上7:00,费率为15分钟,因此将在7:15发送。如果当前时间为7:10,则发送时间为5分钟或更长 300秒

致命错误:允许的内存大小33554432字节已用尽(已尝试) 要在第0行的未知位置分配505364672字节)

更新:

计算未按预期进行:

TIMESTAMPDIFF(第二个,UTC_TIMESTAMP(),来自_UNIXTIME(UNIX_TIMESTAMP()) +alerts.email_rate*60)作为发送

将此用作测试。。。差应该是900秒,但它返回-13500

TIMESTAMPDIFF(第二个,UTC_TIMESTAMP(),来自_UNIXTIME(UNIX_TIMESTAMP()) +15*60)作为输入

更新:

我的部分出错-这将返回正确的值:

TIMESTAMPDIFF(第二个,NOW(),来自UNIXTIME(UNIX\u TIMESTAMP()+15* 60)如图所示

工作解决方案:

它看起来有点邋遢,但这个管用。TIMESTAMPDIFF使用当前时区。。。我的
last_email
值是一个unix时间戳,它是FROM_UNIXTIME发挥作用的地方。因为
last\u email
是一个无符号整数,除非将其转换为有符号整数,否则该算法将无法正常工作。我总是将时间戳设置为unsigned的原因是因为永远不会有负数,但是在使用MySQL进行算术的情况下,这会导致一个问题

TIMESTAMPDIFF(秒,现在为(), 从\u UNIXTIME(转换(警报。最后一封电子邮件,已签名)+警报。电子邮件\u费率* 60)如图所示


这似乎是一个PHP错误,而不是MySQL错误。我怀疑调用
fetchAll
函数时会发生此错误;导致错误的是数组
$results
的分配。(我只是猜测。)根据错误消息,有人试图分配近482MB的内存,但PHP限制为32MB

(我认为PHP中有一个设置设置了这个限制,但我不认为您真的想去那里……因为似乎没有任何理由需要分配那么多内存

问题的一部分是fetchAll,它同时将resultset中的每一行检索到内存中

但是,如果只有在选择列表中添加最后一个表达式时才会发生这种情况,我怀疑PDO为最后一个表达式的结果保留了大量的内存正在使用一些巨大的分配来存储它


要调试此表达式,请尝试更改该查询以返回一个文本整数值来代替最后一个表达式,即替换为:

alerts.last_email + (alerts.email_rate * 60) - UNIX_TIMESTAMP() AS sends_in
为此:

42 AS sends_in 
然后查看PHP是否发出了相同的错误消息。如果不是,我怀疑PDO没有将原始表达式视为简单的整数类型。下一步是将该表达式的结果强制转换或转换为整数数据类型…
CONVERT(expr,UNSIGNED)
CONVERT(expr,SIGNED)

也就是说,将最后一个表达式替换为:

CONVERT(alerts.last_email + (alerts.email_rate * 60) - UNIX_TIMESTAMP(),SIGNED) 
  AS sends_in
旋转一下,看看这个烟球有多大

就实际的MySQL语句而言,我认为在尝试减去无符号整数时可能会出现错误。(我认为SQL_模式中有某种东西控制了这种行为,我认为这种行为取决于MySQL版本。)可能需要将无符号整数转换/强制转换为有符号(64位)整数,像这样难看的东西可能有用:

CONVERT(CONVERT(alerts.last_email,SIGNED) + (CONVERT(alerts.email_rate,SIGNED) * 60) 
  - CONVERT(UNIX_TIMESTAMP(),SIGNED),SIGNED)
  AS sends_in
就我个人而言,我希望避免使用带有datetime和timestamp值的无符号整数数学,并使用MySQL datetime函数



我不确定我是否回答了你的问题。我甚至不确定你是否问了问题。

这不是mysql错误。你可能返回了太多的数据行,导致内存过载。在这个测试中,只有两行数据……在没有最后一次选择的情况下,效果非常好。你尝试过使用mysql的内置函数吗s?
TIMESTAMPDIFF(第二个,来自UNIXTIME(alerts.last\u email+alerts.email\u rate*60),现在()正如
或类似文件中的发送_一样?理想情况下,时间将存储为DATETIME而不是INT…@miken32-虽然我需要颠倒值的顺序,但这是有效的。老实说,我不知道这是存在的,但仍然好奇为什么其他方法不起作用。另外,现在()返回当前时区…我需要UTC格式。@miken32-谢谢…上面有一个有效的解决方案,部分符合您的建议。显式设置为42可以很好地工作。使用第一个转换表达式会产生完全相同的错误。使用第二个表达式可以工作。我想您已经把它钉在头上了-这是使用无符号整数…我有一直这样做是出于习惯,但在这种情况下,这是导致问题的原因。在上面添加了一个工作解决方案,使用了datetime函数并需要转换我自己的时间戳值。谢谢!
CONVERT(CONVERT(alerts.last_email,SIGNED) + (CONVERT(alerts.email_rate,SIGNED) * 60) 
  - CONVERT(UNIX_TIMESTAMP(),SIGNED),SIGNED)
  AS sends_in