SQLite 按日期删除行

SQLite delete rows by date

我一直在搜索,但我仍然无法理解它是如何工作的。

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

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

我见过有人在做这些类型的比较,即使是 TEXT 类型。我对我没有意义。

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

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

在 SQLite 端日期 comparisons/arithmetic 方面更有效和更简单的方法是将日期存储为 SQLite 中的 INTs。

Android 中的

Date 实际上只是 milliseconds-since-the-Epoch 的容器(自 1970 年 1 月 1 日午夜 UTC 以来的毫秒数),它与时区无关。

SQLite 中的

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

为了在数据库中存储数据时将 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);

tl;博士

  • 以标准 ISO 8601 方式将 date-only 值存储为字符串:YYYY-MM-DD
  • 使用 java.time class 中的 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() + "' ;" ;

详情

请记住 SQLite was never meant to be a heavy-duty database,这只是将文本写入文件的一个步骤。因此,如果您需要复杂的 date-time 支持,您应该切换到更复杂的数据库。

正如您在问题中提到的,SQLite 缺少合适的数据类型。为了存储 date-time 类型,文档建议了三个路径 :(a) ISO 8601 字符串,(b) 表示 Julian 日数的实数(我不推荐this) 和 (c) 整数,用于存储自 1970 年第一时刻的纪元参考以来的秒数,如 所示(尽管您不应该使用 Date class 显示在那里)。

您似乎在跟踪 date-only 值,但没有时间。所以我会使用 ISO 8601 作为文本:YYYY-MM-DD.

Java中的java.time类型在parsing/generatingdate-time时默认使用标准ISO 8601格式值。 Java 中的 date-only class 是 LocalDate,缺少 time-of-day 并且缺少时区。

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 格式的优点是字母顺序恰好也是时间顺序。

因此您可以使用 greater-than/less-than 逻辑进行 text-based 比较。

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

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

  • 试图用小数实数表示 date-time 很麻烦。
  • 存储 count-from-epoch 会使调试和故障排除变得困难,因为人类无法轻易读取数据的含义。

关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

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

从哪里获得java.time classes?

  • Java SE 8, Java SE 9,及以后
    • Built-in。
    • 标准 Java API 的一部分,带有捆绑实施。
    • Java 9 添加了一些小功能和修复。
  • Java SE 6 and Java SE 7
    • java.time 的大部分功能是 back-ported 到 Java ThreeTen-Backport 中的 6 和 7。
  • Android
    • Android java.time classes.
    • 捆绑实施的更高版本
    • 对于较早的 Android (<26),ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See .