2012-07-13 65 views
1

我試圖選擇SQLite數據庫中的所有記錄在日後有日期。rails3 sqlite日期比較返回空集

Record.where('scheduled_date > ?', Time.now) 

在我的電腦上,這當前返回一個空數組。

不過,如果我使用以下命令:

Record.all.map { |record| record if record.scheduled_date > Time.now } 

我收到的所有記錄與將來的日期的數組。

此外,我的同事在他的機器上運行相同的Rails項目能夠使用ActiveRecord查詢成功返回預期的結果數組。在最近取消對項目的更改後,此查詢未能爲他工作,他的計算機的行爲與我的相似。

我懷疑在這個Rails項目中SQLite(v.1.3.6)或Rails3(v.3.2.3)可能會造成環境災難,並且不知道在哪裏尋找。任何想法可能會造成這種情況?

+1

這可能是一個UTC問題。當您通過Ruby Record.all.map加載時,記錄日期已經轉換爲UTC。但在Time.now的where子句中是當地時間。如果你使用Time.now.iso8601,你會得到什麼? – peterept 2012-07-14 10:37:41

+0

謝謝peterept,Time.now.iso8601解決了這個問題! – 2012-07-16 15:07:15

回答

0

我和我的sqlite3開發數據庫有類似的問題。

我們使用ActiveSupport :: TimeWithZone :: to_s(:db)爲種子數據庫(調用ActiveRecord :: connection.execute的速度 - 不要判斷我爲我的同事的代碼:)。

sql =<<-EOL 
    INSERT INTO some_table(day) 
    VALUES('#{Time.zone.now.beginning_of_day.to_s(:db)}') 
EOL 
SomeTable.connection.execute(sql) 

對於查詢,我將一個TimeWithZone範圍傳遞給語句中的一個ARel(以在其間生成一個sql)。

SomeTable.where(SomeTable.arel_table[:day].in((Time.zone.now.beginning_of_day)..(1.day.from_now))) 

時間戳從to_s(:DB)看起來是這樣的:2013-10-01 04:00:00

在AREL生成的查詢中的時間戳看起來是這樣的:2013-10-01 04:00:00.000000

即使這些應該是等價的,數據庫解釋後者比前者晚。我無意中偶然發現了小數秒的差異,它看起來像我的sqlite3實現bug(請參閱:https://bugs.freedesktop.org/show_bug.cgi?id=50575)。

我有一種感覺,這可能不是你的問題(因爲iso8601解決了它),但希望這可以節省別人一些挫折!

0

問題源於SQLite將日期時間值存儲爲字符串的事實。因此,您必須完全匹配格式,並將字典排序順序考慮在內。有了mySQL,Oracle,Postgres等,其中列有一個獨特的數據類型,這從來都不是問題。

獲得預期結果的另一種方法是執行「datetime(the_column)> =?」或者甚至是「datetime(the_column)> = datetime(?)」,儘管這當然效率要低得多。