SQLite按日期删除行

问题描述 投票:0回答:3

我一直在寻找,我仍然无法理解这是如何工作的。

我知道SQLite不存储Date类型值,我们必须将它们格式化为TEXT。我已经这样做了,但我的问题是如何按日期删除它们?

因为如果我做DELETE * FROM TABLE WHERE COLUMN_DATE >= '09-05-2017',我会比较字符串而不是日期,所以我想比较不对。

我已经看到人们进行这种类型的比较,即使它是TEXT类型。我对我没有意义。

java android sql sqlite android-database
3个回答
2
投票

如果您使用规范文本格式并使用正确的语法,它将起作用,例如,

DELETE FROM TABLE WHERE COLUMN_DATE >= '2017-05-09'

0
投票

在SQLite边日期比较/算术方面,更有效和更简单的方法是在SQLite中将日期存储为INTs。

Android中的Date实际上只是毫秒级以来的容器(自1970年1月1日以来的UTC时间以来的几毫秒),这是时区独立的。

SQLite中的INT是根据列中的值自动选择的1,2,4,8字节数据类型。

为了在DB中存储数据时将Java Date转换为SQLite INT值,请使用getTime()方法:

Date javaDate = ...;
long sqlDate = date.getTime();

要从SQLite中检索日期,请使用CursorgetLong()方法并将其传递给Date(long)构造函数:

SQLiteDatabase db = ...;
Cursor c = db.query(..);
long sqlDate = c.getLong(...);
Date javaDate = new Date(sqlDate);

0
投票

tl;dr

  • 以标准ISO 8601方式将日期值存储为字符串:YYYY-MM-DD
  • 使用来自java.time类的ISO 8601字符串进行查询,特别是LocalDate

例:

LocalDate ld = LocalDate.of( 2017 , Month.JANUARY , 23 ) ; // Or `LocalDate.parse`, or `LocalDate.now()`.
String sql = "DELETE * FROM tbl WHERE col >= '" + ld.toString() + "' ;" ;

Details

请记住,SQLite was never meant to be a heavy-duty database,只是从文本写入文件的一步。因此,如果您需要复杂的日期时间支持,则应切换到更复杂的数据库。

正如您在问题中提到的那样,SQLite缺少正确的数据类型。对于存储日期时间类型,the documentation suggests three routes:(a)ISO 8601字符串,(b)表示朱利安日数的实数(我不建议这样),以及(c)存储自第一时刻的历元参考以来的秒数的整数在UTC中的1970年,如Answer by Abakumov所示(尽管你不应该使用那里显示的Date类)。

您似乎正在跟踪仅限日期的值,而不是一天中的某个时间。所以我会使用ISO 8601文本:YYYY-MM-DD。

在解析/生成日期时间值时,Java中的java.time类型默认使用标准的ISO 8601格式。 Java中仅限日期的类是LocalDate,缺少时间和缺少时区。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate today = LocalDate.now( z ) ;

指定日期。

LocalDate ld = LocalDate.parse( "2017-09-05" ) ;  // Standard ISO 8601 format for input: YYYY-MM-DD.

标准ISO 8601格式的优点是字母顺序也恰好按时间顺序排列。

因此,您可以使用大于/小于逻辑来进行基于文本的比较。

String sql = "DELETE * FROM tbl WHERE col >= '" + ld.toString() + "' ;" ;

与其他两种方法相比的另一大优势:

  • 试图用小数实数来表示日期时间是混乱的。
  • 存储count-from-epoch使得调试和故障排除变得困难,因为人类无法轻易读取数据的含义。

About java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,如java.util.DateCalendarSimpleDateFormat

现在在Joda-Timemaintenance mode项目建议迁移到java.time班。

要了解更多信息,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规格是JSR 310

您可以直接与数据库交换java.time对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

© www.soinside.com 2019 - 2024. All rights reserved.