【问题标题】:Activerecord, select on string compareActiverecord,选择字符串比较
【发布时间】:2009-06-29 02:26:14
【问题描述】:

我有一个名为 Basic 的表,start_time 是一个类型为 :VARCHAR(5) 的字段,它实际上存储了 5 个字节的时间数据:字节 0 和 1 映射到年、月和日,字节 2 到 4 映射到小时、分钟和秒。所以,字节 2 ,3 ,4 可能都是 0。我想做以下查询:

Basic.find (:all , :conditions => "start_time > ? AND end_time < ?" , start_time , end_time)

以下是问题:

假设 VARCHAR(5) 格式,开始时间为 [214, 222,0 ,0, 0] (Jun, 24th, 2009),结束时间为 [214, 223, 0, 0, 0] ( 2009 年 6 月 25 日)。

由于 activerecord 将 VARCHAR(5) 映射到 String ,所以在上面的查询中 start_time 和 end_time 也应该是 String。将上述 VARCHAR(5) 格式时间转换为字符串的正确方法是什么?

我是这样做的,但没有得到正确的结果:

tmp = [214, 222,0 ,0 ,0].map {|t| t.to_s(16)} ; start_time = tmp.to_s

我正在使用 sqlite3 适配器进行 activerecord。

感谢您的帮助。


我发现问题出在哪里:"\000" is not allowed in the start_time when do follwing query:

Basic.find (:all , :conditions => "start_time > ? AND end_time < ?" , start_time , end_time)

所以,我需要做两步:

  1. [214, 222,0 ,0, 0] - > [214,222]

  2. [214,222] -> "\326\336"

第一步可以使用:

a = [214,222,0,0,0] 
while a.last ==0 do a.pop end

第二步可以使用:

a = [214,222]
a.pack("c" * a.size)

但是,当 start_time = [214, 222,0 ,23, 0] 时我仍然无法查询,因为对应的字符串中间包含“\000”。幸运的是,在我们的应用程序中这不会是一个大问题,因为我们从不以小时为单位进行查询,这意味着最后两个数字将始终为 0。

【问题讨论】:

  • 你为什么不使用日期类型?如果您使用的是 SQLite,我认为这不是旧版设置...
  • 旧数据库以原始格式保存时间 - MJD 表示年份,BCD 编码表示小时、分钟和秒。它在使用 sqlite3 API 时运行良好,到目前为止我还没有看到任何令人信服的理由将其保存为日期类型。

标签: sql ruby string sqlite activerecord


【解决方案1】:

这就是你所追求的吗?

[214, 222, 0, 0, 0].inject(""){|s,c| s << c.chr; s} # => "\326\336\000\000\000"

至于我为什么知道这个......我想在推特上说一次传销,但实际上没有说出来。因为如果你真的这么说,你会被所有这些传销垃圾邮件发送者自动关注。所以我说

[77, 76, 77].inject(""){|s,c| s << c.chr; s}

不过,就您而言,为了避免使用时间戳似乎需要做很多工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    相关资源
    最近更新 更多