问题描述
如果列表中包含 as_counter,t_ms
且值 as_counter
和 t_ms
存在于列表中,我想删除表中的行。
CREATE TABLE Event(
as_counter TEXT NOT NULL,t_ms TEXT NOT NULL,event_map TEXT NOT NULL,PRIMARY KEY (as_counter,t_ms)
);
insertEvent:
INSERT OR REPLACE INTO Event (as_counter,t_ms,event_map)
VALUES (?,?,?);
deleteEventListByKey:
DELETE FROM Event
WHERE (as_counter,t_ms) IN (VALUES(?,?))
我尝试过的方法是在 deleteEventListByKey 中。然而我收到了
'(',')','.',<binary like operator real>,BETWEEN or IN expected,got ','
的错误。我不确定为什么会收到此错误。
我试图通过的测试用例
@Test
fun `delete events by list of primary keys`() {
queries.insertEvent("1","1","{Click,Open}")
queries.insertEvent("1","2",Close},{Read,"3",Open}")
queries.insertEvent("2",Open}")
queries.deleteEventsByKey([("1,2"),("1,1")])
assertthat(queries.selectAllEvents().executeAsList())
.containsExactly(
Event(
as_counter = "1",t_ms = "1",event_map = "{Click,Open}"
),Event(
as_counter = "1",t_ms = "2",Open}"
)
)
}
有谁知道如何为 sqldelight(sqlLite) 编写查询,其中给定列表输入,如果数据库中存在 as_counter
和 t_ms
,则表中的条目将被删除?
解决方法
这是 SQLdelight 的限制。我最终得到了以下解决方案:
deleteEventListByKey:
DELETE FROM Event
WHERE as_counter || ',' || t_ms IN :countersAndMs
像这样使用它:
.deleteEventListByKey(
countersAndMs = listOf("1,2","1,1")
)
或者在一般情况下:
.deleteEventListByKey(
countersAndMs = events.map {
"${it.as_counter},${it.t_ms}"
}
)
这里发生了什么:对于 sql 中的每一行,您正在将一个字符串(在 sqlite '||' 中将左右属性合并为一个字符串)与所有需要的属性进行连接,并将其与一个字符串列表进行比较,您可以必须以同样的方式填写。
请注意,我使用“,”作为分隔符,但如果您的文本数据可能包含此符号,您应该寻找其他符号。
这并不干净,因为我们失去了类型安全性,但我怀疑我们现在还能做些什么。