SQLite 中的日期不起作用
Posted
技术标签:
【中文标题】SQLite 中的日期不起作用【英文标题】:Date in SQLite not working 【发布时间】:2018-12-13 08:59:27 【问题描述】:为什么当我执行我的代码时它会返回表格的所有日期
代码
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|
但是当我尝试这样做时,我会得到表格的所有日期
【问题讨论】:
a/ 请将random date
替换为未能给出预期b/ 的实际示例,您的日期首先如何存储在数据库中?您确定它看起来与您在问题中包含的内容完全一样吗? c/您似乎出于某种原因使用的变量date
的值是多少?显然它应该有date
列的名称,但可能没有?
【参考方案1】:
当您使用原始版本时,您实际上是在发出查询:-
SELECT * FROM database1 WHERE date(date)<='random date';
即它将返回日期(例如字符串2018-01-01)小于或等于字符串随机日期的所有行。因此,由于 r 大于 2(或任何数字作为字符),因此它将返回所有行。
更具体地说:-
random 不是返回随机数的函数,随机日期也不是尝试 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());
注意 上面假设使用String
而不是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
回复:-
注意:当我说“随机日期”时,我指的是我放入的任何日期 括号不是函数'random()',例如我把 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
回复:-
最简单的解决方案是始终使用 10 字符格式,即 yyyy-mm-dd,而不是 8-10 字符格式,例如
使用 2017-06-24 或 2017-06 而不是 2017-6-24 或 2017-6-1 -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....
【讨论】:
当我说“随机日期”时,我指的是我放在括号内的任何日期,而不是函数'random()',例如,我把 8-6-2018 放在哪里是“随机date" 即 date 您应该编辑您的问题以澄清。与其提供不同且模棱两可的代码,不如提供您正在使用的实际代码。您还应该给出一个随机日期或随机日期的示例,以及它是如何在您的编码器中传递的。还要显示日期如何存储在日期列中。 很抱歉让您浪费时间。我编辑了我的问题以使其更清楚 学习曲线的所有部分都没有问题,将尝试在适当的时候提出解决方案。当您更改为可用格式时,它应该很容易。如果月份总是 2 个字符会简单得多(我假设这个) 非常感谢你,现在我得到了我想要的日期。如果我第一次提问就让你浪费了时间,我真的很抱歉。以上是关于SQLite 中的日期不起作用的主要内容,如果未能解决你的问题,请参考以下文章
父 - 事务下 PHP PDO SQLite 中的子表 - 没有错误,但它不起作用