SQLite, tarihleri depolamak için metin, gerçek veya tamsayı veri türlerini kullanabilir. Dahası, her sorgu yaptığınızda sonuçlar format kullanılarak gösterilir %Y-%m-%d %H:%M:%S
.
Şimdi, SQLite tarih / saat işlevlerini kullanarak tarih / saat değerleri ekler / güncellerseniz, gerçekten de milisaniye depolayabilirsiniz. Bu durumda, sonuçlar format kullanılarak gösterilir %Y-%m-%d %H:%M:%f
. Örneğin:
sqlite> create table test_table(col1 text, col2 real, col3 integer);
sqlite> insert into test_table values (
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.123'),
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.123'),
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.123')
);
sqlite> insert into test_table values (
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.126'),
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.126'),
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.126')
);
sqlite> select * from test_table;
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
2014-03-01 13:01:01.126|2014-03-01 13:01:01.126|2014-03-01 13:01:01.126
Şimdi, zamanları gerçekten karşılaştırabildiğimizi doğrulamak için bazı sorgular yapmak:
sqlite> select * from test_table /* using col1 */
where col1 between
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.121') and
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.125');
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
Aynı kontrol edebilirsiniz SELECT
kullanarak col2
ve col3
ve aynı sonuçları alırsınız. Gördüğünüz gibi, ikinci satır (126 milisaniye) döndürülmez.
BETWEEN
Kapsayıcı olduğunu unutmayın , bu nedenle ...
sqlite> select * from test_table
where col1 between
/* Note that we are using 123 milliseconds down _here_ */
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.123') and
strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.125');
... aynı seti döndürür.
Farklı tarih / saat aralıklarıyla oynamayı deneyin, her şey beklendiği gibi davranacaktır.
strftime
İşlevsiz ne olacak ?
sqlite> select * from test_table /* using col1 */
where col1 between
'2014-03-01 13:01:01.121' and
'2014-03-01 13:01:01.125';
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
Ne yaklaşık olmadan strftime
işlev ve hiçbir milisaniye?
sqlite> select * from test_table /* using col1 */
where col1 between
'2014-03-01 13:01:01' and
'2014-03-01 13:01:02';
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
2014-03-01 13:01:01.126|2014-03-01 13:01:01.126|2014-03-01 13:01:01.126
Ne olmuş ORDER BY
?
sqlite> select * from test_table order by 1 desc;
2014-03-01 13:01:01.126|2014-03-01 13:01:01.126|2014-03-01 13:01:01.126
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
sqlite> select * from test_table order by 1 asc;
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
2014-03-01 13:01:01.126|2014-03-01 13:01:01.126|2014-03-01 13:01:01.126
Sadece iyi çalışıyor.
Son olarak, bir program içindeki gerçek işlemlerle uğraşırken (sqlite çalıştırılabilir dosyası kullanmadan ...)
BTW: JDBC (diğer diller hakkında emin değilim) kullanıyorum ... xerial'dan sqlite-jdbc sürücüsü v3.7.2 - belki daha yeni düzeltmeler aşağıda açıklanan davranışı değiştirir ... Android'de geliştiriyorsanız, bir jdbc sürücüsü gerekir. Tüm SQL işlemleri SQLiteOpenHelper
.
JDBC bir veritabanından gerçek tarih / zaman değerlerini almak için farklı yöntemler vardır: java.sql.Date
, java.sql.Time
, ve java.sql.Timestamp
.
İlgili yöntemler java.sql.ResultSet
(tabii ki) olan getDate(..)
, getTime(..)
ve getTimestamp()
sırasıyla.
Örneğin:
Statement stmt = ... // Get statement from connection
ResultSet rs = stmt.executeQuery("SELECT * FROM TEST_TABLE");
while (rs.next()) {
System.out.println("COL1 : "+rs.getDate("COL1"));
System.out.println("COL1 : "+rs.getTime("COL1"));
System.out.println("COL1 : "+rs.getTimestamp("COL1"));
System.out.println("COL2 : "+rs.getDate("COL2"));
System.out.println("COL2 : "+rs.getTime("COL2"));
System.out.println("COL2 : "+rs.getTimestamp("COL2"));
System.out.println("COL3 : "+rs.getDate("COL3"));
System.out.println("COL3 : "+rs.getTime("COL3"));
System.out.println("COL3 : "+rs.getTimestamp("COL3"));
}
// close rs and stmt.
SQLite gerçek bir DATE / TIME / TIMESTAMP veri türüne sahip olmadığından, bu 3 yöntemin tümü, nesneler 0 ile başlatılmış gibi değerleri döndürür:
new java.sql.Date(0)
new java.sql.Time(0)
new java.sql.Timestamp(0)
Yani soru şu: Tarih / Saat / Zaman Damgası nesnelerini nasıl seçebilir, ekleyebilir veya güncelleyebiliriz? Kolay bir cevap yok. Farklı kombinasyonları deneyebilirsiniz, ancak SQLite işlevlerini tüm SQL deyimlerine gömmeye zorlarlar. Metni Java programınızdaki Date nesnelerine dönüştürmek için bir yardımcı program sınıfı tanımlamak çok daha kolaydır. Ancak SQLite'nin herhangi bir tarih değerini UTC + 0000'a dönüştürdüğünü unutmayın.
Özet olarak, her zaman doğru veri türünü kullanmak için genel kurala veya Unix zamanını (çağdan beri milisaniye) ifade eden tamsayılara rağmen, tüm SQL ifadelerinizi karmaşıklaştırmak yerine varsayılan SQLite biçimini ( '%Y-%m-%d %H:%M:%f'
veya Java'da 'yyyy-MM-dd HH:mm:ss.SSS'
) kullanmaktan çok daha kolay buluyorum SQLite fonksiyonları. Önceki yaklaşımın sürdürülmesi çok daha kolaydır.
YAPILACAKLAR: Android içinde (API15 veya daha iyisi) getDate / getTime / getTimestamp kullanırken sonuçları kontrol edeceğim ... belki dahili sürücü sqlite-jdbc'den farklı ...