SQLite中的日期不起作用

时间:2018-07-04 23:38:50

标签: android sqlite date android-studio android-sqlite

为什么当我执行代码时,它会返回表的所有日期

代码

    Strign raw[] = {"id","date"}
    String args[] ={"2017-6-24"} 
    Cursor cursor = database.query("database1", raw , date + "<=?"
                        , args, null, null, null);

我尝试过但没有成功的事情:

1)我尝试在代码中放入“日期(示例日期)”

    Strign raw[] = {"id","date"}
    String args[] ={"date(2017-6-24)"} 
    Cursor cursor = database.query("database1", raw , "date("+date + ")<=?"
                        , args, null, null, null);

2)

    Strign raw[] = {"id","date"}
    String args[] ={"2017-6-24"} 
    Cursor cursor = database.rawQuery("SELECT * FROM database1 "+ 
                                       "WHERE date<="+"2017-6-24",null);

编辑

在我的应用中,我需要返回特定于某一日期的所有日期,即如果我的日期表中包含此日期

     | ID |   DATE   |
     -----------------
     |  1 | 2018-6-21|
     |  2 | 2015-5-12|
     |  3 | 2013-3-17|
     |  4 | 2017-2-13|

然后我在应用中输入日期'2017-6-24',我需要返回该日期之前的所有日期,即我需要获取

     | ID |   DATE   |
     -----------------
     |  2 | 2015-5-12|
     |  3 | 2013-3-17|
     |  4 | 2017-2-13|

但是当我尝试这样做时,我会得到表格的所有日期

1 个答案:

答案 0 :(得分:2)

使用原件时,您实际上是在发出查询:-

SELECT * FROM database1 WHERE date(date)<='random date';

即它将返回日期(例如字符串 2018-01-01 )小于或等于字符串随机日期的所有行。因此,当 r 大于 2 (或任何数字作为字符)时,它将返回所有行。

更具体地说:-

  • 随机不是返回随机数的函数,也不是随机日期

尝试1将有效地发出查询:-

SELECT id,date FROM database1 WHERE date(date)<='date(random date)';

即如上,但第一个字符将为 d

尝试2将有效地发出查询:-

SELECT * FROM database1 WHERE date<=random date;

会因为诸如near "date": syntax error

这样的语法错误而失败

更具体地说:-

  • random不是返回随机数的函数,也不是随机日期返回随机日期的函数。 random()是SQLite的核心功能之一,可用于返回随机的64位带符号整数。

    • 通过rawQuery的第二个参数或query的第四个参数传递的任何参数将导致该值作为字符串括起来,因此SQLite函数不能作为参数传递,因为它们将被括起来视为字符串。

您似乎想根据:-

SELECT * FROM database1 WHERE date<=date(random());
  • 注意,以上假设Strign代替String用作 raw 变量的类型。

并非上面的方法有效。简而言之(例如,必须使用datetime(),还必须使用“ uniepoch”使用整数和其他一些操作),这将导致从1970年到迄今为止的大量日期今天出生的人您可能希望在相对较短的定义时间范围内获取日期,以返回所有行。

因此,假设您要根据从当前日期起一年内的某个日期随机排列一组行,那么您可能会有:-

SELECT * FROM database1 WHERE  date <= date('now','+'||(ABS(random())%365)||' DAYS');

这是在做:-

  • 生成一个随机数,该随机数具有很大的范围,负值和正值,然后
    • 使用ABS(n)函数返回正值。
    • 将该数字除以365(相当于1年的天数)后,返回模数(余数)。
    • 将该天数添加到当前日期,以得出从现在起一年内的某个日期,作为WHERE子句的正确参数。

可以使用:-

String raw[] = {"id","date"}
Cursor cursor = database.query("database1", raw , date <= date('now','+'||(ABS(random())%365)||' DAYS')
                    , null, null, null, null);
  • 请注意,这不一定是您想要的,您实际上并没有阐明您的要求。而是一个示例,说明如何获取一个可能合适或不合适的随机日期(例如,可能想要一个现在之前的日期,在这种情况下, + 可以更改为 - )。

编辑1

re:-

  

注意:当我说“随机日期”时,是指我放入的任何日期   括号不要放在函数“ random()”上,例如我   2018年8月6日在哪里是``随机日期'',即日期<=(8-6-2018)

日期不应采用这种格式,日期应采用(最可能的合适格式) yyyy-mm-dd ,例如 2018-06-08 (同样,它们应该像这样存储在数据库中)

SQLite预期日期格式有限,

SQL As Understood By SQLite - Date And Time Functions -Time Strings

使用SELECT * FROM database1 WHERE date <=(8-6-2018);实际上是说SELECT * FROM database WHERE date <= -2016(即2018年减去8减去6,等于2018年减去2)。

如果不更改为公认的格式,则会遇到很多问题。并不是不可能,但是要使用8-6-2018(以及格式的排列,即8-6-2018(8个字符),10-6-2018现在为9个字符和10-10-2018(10个字符))转换为可用格式的复杂性。

例如您必须使用类似:-

WITH 

 selection_date(sdate) AS ( SELECT '8-6-2018'), --<<<<<<<< selection value

 converted_selection_date(sdate,converted_selection) AS (
        SELECT DISTINCT
            sdate,
            CASE
            WHEN length(sdate) = 8 THEN
                substr(sdate,5,4)||'-0'||substr(sdate,3,1)||'-0'||substr(sdate,1,1)
            WHEN (length(sdate) = 9 AND substr(sdate,2,1) = '-') THEN -- d-mm-yyyy
                substr(sdate,6,4)||'-'||substr(sdate,3,2)|'-0'||substr(sdate,1,1)
            WHEN (length(sdate) = 9 AND substr(sdate,3,1) = '-') THEN -- dd-m-yyyy
                substr(sdate,6,4)||'-0'||substr(sdate,4,1)||'-'||substr(sdate,1,2)
            WHEN (length(sdate) = 10 AND substr(sdate,3,1) = '-') THEN -- dd-mm-yyyy
                substr(sdate,7,4)||'-'||substr(sdate,4,2)||'-'||substr(sdate,1,2)
            ELSE sdate||'----'||length(sdate)
        END AS converted_selection
        FROM selection_date
    ),

 converted_date_column(rid,converted_date) AS (
    SELECT rowid AS rid, 
        CASE 
            WHEN (length(date) = 8 AND substr(date,2,1) = '-') THEN -- d-m-yyyy 
                substr(date,5,4)||'-0'||substr(date,3,1)||'-0'||substr(date,1,1)
            WHEN (length(date) = 9 AND substr(date,2,1) = '-') THEN -- d-mm-yyyy
                substr(date,6,4)||'-'||substr(date,3,2)|'-0'||substr(date,1,1)
            WHEN (length(date) = 9 AND substr(date,3,1) = '-') THEN -- dd-m-yyyy
                substr(date,6,4)||'-0'||substr(date,4,1)||'-'||substr(date,1,2)
            WHEN (length(date) = 10 AND substr(date,3,1) = '-') THEN -- dd-mm-yyyy
                substr(date,7,4)||'-'||substr(date,4,2)||'-'||substr(date,1,2)
            ELSE date
            END AS converted_date
    FROM argent
    )
    SELECT date FROM argent, converted_selection_date WHERE date <= converted_selection
;

编辑2

re:-

最简单的解决方案是始终使用 10个字符格式,即 yyyy-mm-dd 而不是8-10个字符格式,例如

代替 2017-6-24 2017-6-1 使用 2017-06-24 2017-06 -01 。 (即,小于10的月份和日期前导0)

在这种情况下,原件和2)将照原样工作。

1)可能是:-

String raw[] = {"id","date"}
String args[] ={"random date"} 
Cursor cursor = database.query("database1", raw , "date(date)<=date(?)"
                    , args, null, null, null);

即只有值本身才是参数,而where子句的其余部分是硬编码的,因此不加引号。

尽管比上面的示例转换更简单,但是如果格式保持为8-10,则您仍需要像上面那样进行一些转换,以免得到不需要的结果。

例如如果选择日期为2017-2-1,则使用原始格式的结果会少一些,而使用2017-10-1的格式会少一些,而2)(1根本无法正常工作)。因为字符串2017-1 ....小于字符串2017-2 ....