简体   繁体   English

SQLite按日期删除行

[英]SQLite delete rows by date

I have been searching and i still can not understand how this works. 我一直在搜索,但我仍然不明白它是如何工作的。

I know that SQLite doesn't store Date type values and we have to format them to TEXT. 我知道SQLite不存储Date类型的值,我们必须将它们格式化为TEXT。 I already did that, but my question is how do i delete them by date? 我已经做到了,但是我的问题是如何按日期删除它们?

Because if I do DELETE * FROM TABLE WHERE COLUMN_DATE >= '09-05-2017' , I will be comparing Strings and not Dates, so i guess the comparison won't be right. 因为如果我DELETE * FROM TABLE WHERE COLUMN_DATE >= '09-05-2017' ,我将比较字符串而不是日期,所以我猜比较是不正确的。

I have seen people doing these type of comparisons even if it is TEXT type. 我已经看到人们进行这种类型的比较,即使它是TEXT类型。 I doesn't make sense to me. 我对我没有任何意义。

如果您使用规范文本格式并使用正确的语法(例如,

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

A much more efficient and simpler in terms of SQLite side date comparisons/arithmetic is to store dates as INT s in SQLite. 就SQLite边日期比较/算术而言,一种更有效,更简单的方法是在SQLite中将日期存储为INT

Date in Android is effectively just a container for milliseconds-since-the-Epoch (milliseconds since Jan 1st 1970 at midnight UTC) which is time zone independent. 自从Epoch(自1970年1月1日午夜UTC以来的毫秒数)以来,Android中的Date实际上只是一个毫秒数的容器,与时区无关。

INT in SQLite is 1, 2, 4, 8 byte data type automatically chosen depending on values in the column. SQLite中的INT是根据列中的值自动选择的1、2、4、8字节数据类型。

In order to convert a Java Date into a SQLite INT value when storing data in DB, use getTime() method: 为了在将数据存储在DB中时将Java Date转换为SQLite INT值,请使用getTime()方法:

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

To retrieve a date from SQLite, use Cursor 's getLong() method and pass it to Date(long) constructor: 要从SQLite检索日期,请使用CursorgetLong()方法并将其传递给Date(long)构造函数:

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

tl;dr tl; dr

  • Store date-only values as strings in standard ISO 8601 fashion: YYYY-MM-DD 以标准ISO 8601格式将仅日期的值存储为字符串:YYYY-MM-DD
  • Query using ISO 8601 strings from the java.time classes, specifically LocalDate . 使用java.time类(特别是LocalDate ISO 8601字符串进行查询。

Example: 例:

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

Details 细节

Keep in mind that SQLite was never meant to be a heavy-duty database , just a step up from writing text to a file. 请记住, SQLite从来都不是一个重型数据库 ,只是将文本写入文件的一个步骤。 So if you need sophisticated date-time support, you should switch to a more sophisticated database. 因此,如果您需要复杂的日期时间支持,则应切换到更复杂的数据库。

SQLite lacks proper data types, as you alluded in the Question. 正如您在课题中提到的那样,SQLite缺少适当的数据类型。 For storing date-time types, the documentation suggests three routes : (a) ISO 8601 strings, (b) Real number representing Julian day numbers (I don't recommend this), and (c) Integer for storing number of seconds since the epoch reference of first moment of 1970 in UTC as shown in Answer by Abakumov (though you should NOT be using Date class shown there). 为了存储日期时间类型, 文档提出了三种路由 :(a) ISO 8601字符串,(b)代表儒略日数字的实数(我不建议这样做),以及(c)用于存储自如Ubakumov的Answer中所示,以UTC表示1970年第一时刻的时代参考(尽管您不应该使用此处显示的Date类)。

You seem to be tracking date-only values, without a time of day. 您似乎正在跟踪仅日期的值,而没有一天的时间。 So I would use the ISO 8601 for text: YYYY-MM-DD. 因此,我将对文本使用ISO 8601 :YYYY-MM-DD。

The java.time types in Java use the standard ISO 8601 formats by default when parsing/generating date-time values. 解析/生成日期时间值时,Java中的java.time类型默认使用标准ISO 8601格式。 The date-only class in Java is LocalDate , lacking a time-of-day and lacking a time zone. Java中的仅日期类是LocalDate ,缺少日期和时区。

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

Specify a date. 指定日期。

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

The advantage of standard ISO 8601 format is that alphabetical order happens to also be chronological order. 标准ISO 8601格式的优点是字母顺序也按时间顺序排列。

So you can do text-based comparison using greater-than/less-than logic. 因此,您可以使用大于/小于逻辑进行基于文本的比较。

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

Another big advantage over the other two approaches: 与其他两种方法相比的另一大优势:

  • Trying to represent date-time with a fractional real number is messy. 试图用小数实数表示日期时间很麻烦。
  • Storing a count-from-epoch makes debugging and troubleshooting difficult as a human cannot readily read the meaning of the data. 由于无法从中读取数据的含义,因此存储从时间开始的计数使调试和故障排除变得困难。

About java.time 关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat . 这些类取代了麻烦的旧的旧式日期时间类,例如java.util.DateCalendarSimpleDateFormat

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes. 现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial . 要了解更多信息,请参见Oracle教程 And search Stack Overflow for many examples and explanations. 并在Stack Overflow中搜索许多示例和说明。 Specification is JSR 310 . 规格为JSR 310

You may exchange java.time objects directly with your database. 您可以直接与数据库交换java.time对象。 Use a JDBC driver compliant with JDBC 4.2 or later. 使用与JDBC 4.2或更高版本兼容的JDBC驱动程序 No need for strings, no need for java.sql.* classes. 不需要字符串,不需要java.sql.*类。

Where to obtain the java.time classes? 在哪里获取java.time类?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM