1

我正在尝试选择 SQLite DB 中具有未来日期的所有记录。

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) 可能存在环境事故,不知道去哪里找。有什么想法可能导致这种情况吗?

4

2 回答 2

0

问题源于 SQLite 将日期时间值存储为字符串这一事实。因此,您必须完全匹配格式,同时考虑到字典排序顺序。对于 mySQL、Oracle、Postgres 等,列具有不同的数据类型,这绝不是问题。

获得预期结果的另一种方法是执行“datetime(the_column) >= ?” 甚至是“datetime(the_column) >= datetime(?)”,尽管这当然效率要低得多。

于 2013-12-12T15:55:59.313 回答
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 in 语句(以在其间生成 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 实现错误(参见:https ://bugs.freedesktop.org/show_bug.cgi?id=50575 )。

我有一种感觉,这可能不是你的问题(因为 iso8601 解决了它),但希望这会给别人一些挫折!

于 2012-10-22T19:32:22.553 回答