2012-07-13 2 views
1

미래에 날짜가있는 SQLite DB의 모든 레코드를 선택하려고합니다.rails3 sqlite 날짜 비교 반환 null 집합

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

내 컴퓨터에서는 현재 빈 배열을 반환합니다. 나는 다음과 같은 사용하는 경우

그러나 :

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

나는 미래의 날짜와 모든 기록의 배열을받을 수 있습니다.

또한 내 컴퓨터에서 동일한 레일스 프로젝트를 실행중인 동료가 ActiveRecord 쿼리를 사용하여 예상 결과 배열을 성공적으로 반환 할 수있었습니다. 최근 프로젝트에 대한 변경 사항을 가져온 후이 쿼리가 작동하지 않고 컴퓨터가 제 것처럼 작동합니다.

이 Rails 프로젝트에 SQLite (1.3.6 버전) 또는 Rails3 (3.2.3 버전)이 설치된 환경에 문제가있을 수 있으며 어디서 볼지 모른다고 생각됩니다. 어떤 아이디어가이 원인 일 수 있습니까?

+1

아마도 UTC 문제 일 수 있습니다. Ruby Record.all.map을 통해로드 할 때 레코드 날짜가 이미 UTC로 변환됩니다. 그러나 where 절에서 Time.now는 현지 시간입니다. Time.now.iso8601을 사용하면 무엇을 얻게됩니까? – peterept

+0

감사합니다. Peterept, Time.now.iso8601이 문제를 해결했습니다! –

답변

0

내 sqlite3 개발 DB에서 비슷한 문제가있었습니다.

우리가 사용하고 ActiveSupport :: TimeWithZone :: 그리고 to_s (: dB) 액티브는 :: 속도 connection.execute 호출 DB (씨앗하기 - 내 동료의 코드 : 나를 판단하지 않습니다를. 쿼리에 대한

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

, 나는 문에 ARel에 TimeWithZone 범위를 통과했다 (사이에 SQL을 생성합니다). 그리고 to_s에서

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

타임 스탬프는 arel 생성 쿼리의 타임 스탬프가 같은 것을 보았다 2013-10-01 04:00:00

: 2013-10-01 04:00:00.000000

에도 이러한 동일해야하지만를, (: dB) 같은 것을 보았다 DB는 후자를 전자보다 나중에 해석했다. 우연히 실수로 초의 차이에 비틀 거려서 영원히 나를 데려 갔고 그것은 sqlite3 구현 버그처럼 보입니다 (https://bugs.freedesktop.org/show_bug.cgi?id=50575 참조).

이 문제는 (iso8601이 해결 한 이래로) 문제가되지 않았을 수도 있지만, 다른 사람에게 약간의 좌절을 안겨줍니다.

0

SQLite가 datetime 값을 문자열로 저장하기 때문에 문제가 발생합니다. 따라서 사전 식 정렬 순서 고려 사항을 고려하여 형식을 정확히 일치시켜야합니다. mySQL, Oracle, Postgres 등에서 열에 고유 한 데이터 유형이있는 경우에는 이것이 결코 문제가되지 않습니다.

예상되는 결과를 얻는 또 다른 방법은 "datetime (the_column)> =?"을 수행하는 것입니다. 심지어는 "datetime (the_column)> datetime (?)"과 같은 표현을 사용합니다.