2014-09-18 244 views
3

我有一個持續的過程,它檢查數據庫表中的一行,並根據子進程最後一次產生的時間(基本上,一個非常簡單的CRON替換)在某個時間間隔產生子進程。減去時間戳差異

我最初實現它,只是從存儲在last_start列中的值中減去當前時間戳。 CURRENT_TIMESTAMP - last_start。這似乎工作,但更仔細的檢查顯示時間戳扣除行爲相當奇怪。

看起來,當我們越過分鐘屏障(所以,當前時間點到一分鐘),計算出的「差異」將跳躍40(例如從59增加到100)。這個看起來像像「1:00」 - 類型 - 直到我們達到如下所示的狀態,其中「秒」部分超過60(在下面的示例中爲95)。

我解決了這個問題,通過使用TIMESTAMPDIFF方法來做減法(謝謝Stack Overflow!)。但是,我不清楚爲什麼這首先失敗了。

mysql db_name -e 'select CURRENT_TIMESTAMP, last_start, CURRENT_TIMESTAMP - last_start , TIMESTAMPDIFF(SECOND, last_start, CURRENT_TIMESTAMP) from tasks where id = 3'  Thu Sep 11 09:49:17 2014 

CURRENT_TIMESTAMP  last_start    CURRENT_TIMESTAMP - last_start  TIMESTAMPDIFF(SECOND, last_start, CURRENT_TIMESTAMP) 
2014-09-11 09:49:17  2014-09-11 09:37:22 1195         715 

任何人都可以向我解釋什麼時候我剛剛減去時間戳,因爲我在做什麼?

編輯:表架構如下:

CREATE TABLE `tasks` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `task` char(128) NOT NULL, 
    `run_count` int(10) unsigned NOT NULL DEFAULT '0', 
    `domina` char(128) DEFAULT NULL, 
    `slave` char(128) DEFAULT NULL, 
    `last_start` timestamp NULL DEFAULT NULL, 
    `last_end` timestamp NULL DEFAULT NULL, 
    `avg_duration` int(10) unsigned NOT NULL DEFAULT '0', 
    `last_status` char(64) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 
+0

'last_start'的數據類型是什麼?處理未存儲在本機類型中的日期和時間時,MySQL可能會很時髦。 – 2014-09-18 20:00:49

+0

添加了create table語句 – v4nz 2014-09-18 20:11:29

+1

使用'timestampdiff()'而不是'-'。 '-'將參數視爲整數,這會導致您的問題。 – 2014-09-18 20:12:54

回答

2

爲什麼這個問題呢?那麼,你會期望一個名爲TIMESTAMP的數據類型的數據庫(或任何其他軟件產品)和一個名爲CURRENT_TIMESTAMP的「常量」將代表後者使用前者。

但是沒有。這不是MySQL。 CURRENT_TIMESTAMPnow()的同義詞,其類型與上下文相關。令人高興的是,文檔解釋這個很清楚:

返回當前日期和時間的值「YYYY-MM-DD HH:MM:SS」 或YYYYMMDDHHMMSS,具體格式取決於是否函數中使用 一個字符串或數字上下文。

當然,你必須弄清楚不同的上下文是什麼。一個提示。 -的使用是一個「數字上下文」。

接下來會發生什麼。 MySQL會看到CURRENT_TIMESTAMP並放入當前時間。但是如何?它看到-並確定它作爲一個數字。然後它遇到last_start。那麼,現在也必須轉換成一個數字。你猜怎麼着?你會得到時髦的行爲。

+0

'會代表後者使用前者的精彩(而且很奇怪) – 2014-09-19 05:12:44