/* Just in case Environment is dirty */
DROP TABLE IF EXISTS example;
/* Create the table */
CREATE TABLE IF NOT EXISTS example (startdatetime INTEGER, enddatetime INTEGER);
/* Load the table with some data */
WITH cte(onedatetime) AS (
SELECT datetime('now') UNION ALL SELECT datetime(onedatetime,'+1 Hour') FROM cte LIMIT 10
)
INSERT INTO example SELECT onedatetime,onedatetime FROM cte;
/* The data loaded */
SELECT * FROM example;
/* The demonstration */
SELECT * FROM example WHERE startdatetime BETWEEN (SELECT startdatetime FROM example ORDER BY startdatetime ASC LIMIT 1) AND (SELECT startdatetime FROM example ORDER BY startdatetime ASC LIMIT 1);
/* Clean Up Test Environment */
DROP TABLE IF EXISTS example;
结果1**已加载的数据(请注意,由于日期时间基于当前日期时间,因此每次运行时数据都会发生变化):-
请注意,突出显示的行将用于BETWEEN .... AND ....子句的两个值。
结果2**
子查询(SELECT startdatetime FROM example ORDER BY startdatetime ASC LIMIT 1)确保日期相同(按照示例表中第一行)
@Query("SELECT * FROM example WHERE startdatetime BETWEEN :startDateTime AND :endDateTime AND enddatetime BETWEEN :startDateTime AND :endDateTime;")
fun getExamplesBetweenDateTimes(startDateTime: String, endDateTime: String): List<Example>
房间演示**
使用@Entity:-
@Entity
data class Example(
@PrimaryKey
val exampleId: Long?=null,
val startdatetime: String,
val enddatetime: String
)
有没有解决方案可以使数据库拒绝相同开始时间和结束时间 如果它是原生SQLite,那么可以使用CHECK约束以及**INSERT OR IGNORE**。然而,尽管Room支持INSERT OR IGNORE,例如@Insert(onConflict = OnConflictStrategy.IGNORE)。Room不通过注解提供对CHECK的支持(并非不可能实现(我相信))。 但是,以下内容可用于有效模拟检查:
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(example: Example): Long
@Query("")
fun insertRestrictedExample(example: Example): Long {
if (example.startdatetime != example.enddatetime) return insert(example)
return -1
}
请注意,绝不会直接调用insert函数(除非需要使用相同的开头和结尾进行插入)
相应地扩展演示**
例如,如果使用了以下内容:-
val dt01 = "2023-01-01 20:00"
val dt02 = "2023-01-01 21:00"
val dt03 = "2023-01-01 19:00"
daox.insertRestrictedExample(Example(startdatetime = dt01, enddatetime = dt01))
daox.insertRestrictedExample(Example(startdatetime = dt01, enddatetime = dt02))
daox.insertRestrictedExample(Example(startdatetime = dt02, enddatetime = dt02))
daox.insertRestrictedExample(Example(startdatetime = dt02, enddatetime = dt03))
daox.insertRestrictedExample(Example(startdatetime = dt03, enddatetime = dt03))
for (e in daox.getExamplesBetweenDateTimesButNotIfSameStartAndEndPassed(dt01,dt01)) {
Log.d(
"DBINFO1",
"Example extracted where startdatetime is ${e.startdatetime} and enddatetime is ${e.enddatetime} ID is ${e.exampleId}"
)
}
for (e in daox.getAllFromExample()) {
Log.d(
"DBINFO2",
"Example extracted where startdatetime is ${e.startdatetime} and enddatetime is ${e.enddatetime} ID is ${e.exampleId}"
)
}
即新的insertRestrcitedExample和提取ALL行的查询,则结果将为
:-
D/DBINFO2: Example extracted where startdatetime is 2023-01-01 20:00 and enddatetime is 2023-01-01 21:00 ID is 1
D/DBINFO2: Example extracted where startdatetime is 2023-01-01 21:00 and enddatetime is 2023-01-01 19:00 ID is 2
@Query("SELECT * FROM example WHERE startdatetime BETWEEN :startDateTime AND :endDateTime AND enddatetime BETWEEN :startDateTime AND :endDateTime AND :startDateTime <> :endDateTime;")
fun getExamplesBetweenDateTimesButNotIfSameStartAndEndPassed(startDateTime: String, endDateTime: String): List<Example>
1条答案
按热度按时间jmp7cifd1#
如果开始和结束时间相同怎么办
使用BETWEEN将返回一行,其中存储数据和查询的开始和结束都相同。
考虑下面的演示(这是最后一个查询,也就是结果2),剩下的只是在数据库中创建数据(结果1)。
BETWEEN .... AND ....
子句的两个值。(SELECT startdatetime FROM example ORDER BY startdatetime ASC LIMIT 1)
确保日期相同(按照示例表中第一行)即,即使BETWEEN(开始和结束)的两个值相同,行仍然匹配。
假设example表被定义为Room中的
@Entity
,并且要传递开始和结束日期时间,则@Dao
注解接口/抽象类中的函数可以类似于/基于:-使用
@Entity
:-除了上面的
getExamplesBetweenDateTimes
函数以及其他必要的代码(@Database
注解抽象类,插入示例很有趣),然后使用:-结果:-
2023-01-01 20:00
之间并且结束也在2023-01-01 20:00
之间 (除非考虑毫秒,否则通常不期望任何东西具有相同的开始和结束)。有没有解决方案可以使数据库拒绝相同开始时间和结束时间
如果它是原生SQLite,那么可以使用CHECK约束以及**INSERT OR IGNORE**。然而,尽管Room支持
INSERT OR IGNORE
,例如@Insert(onConflict = OnConflictStrategy.IGNORE)
。Room不通过注解提供对CHECK
的支持(并非不可能实现(我相信))。但是,以下内容可用于有效模拟检查:
例如,如果使用了以下内容:-
insertRestrcitedExample
和提取ALL行的查询,则结果将为:-
即现在仅将开始和结束不同的2行插入到数据库中。
您还可以使用
AND :startDateTime <> :endDateTime
防止提取任何具有相同结尾和开头的数据例如: