在Android SQLite中使用复合主键查询现有行

3mpgtkmj  于 2022-11-15  发布在  SQLite
关注(0)|答案(1)|浏览(121)

我有一个具有复合主键的表。

@Entity(
   tableName = "my_table",
   primaryKeys = ["key1", "key2, "key3"]
)
data class MyTable(
   @ColumnInfo(name = "key1")
   val key1: Int,

   @ColumnInfo(name = "key2)
   val key2: Int,

   @ColumnInfo(name = "key3")
   var key3: String,
) { ... }

我正在从远程数据源获取新记录,当我取回这些记录时,我希望根据复合主键确定数据库中还没有哪些记录。
我认为使用SQL时,我可以使用类似以下内容来确定数据库中已经存在的所有行:

SELECT *
FROM table_name
WHERE (key1, key2, key3) IN ( (1,2,'foo'), (3,4,'bar') );

目前的支持回到了Android API 24,这意味着使用SQLite 3.9。
但是,在SQLite中不支持该语法。根据远程列表查询所有现有行的正确方式是什么?

tquggr8v

tquggr8v1#

您的查询在最新的SQLite版本中工作得很好,但由于您希望在Android上使用它,而Android只支持较旧的版本(目前的SQLite 3.32.2在API级别33),请更改为带有VALUES子句的子查询:

SELECT *
FROM table_name
WHERE (key1, key2, key3) IN (SELECT * FROM (VALUES (1,2,'foo'), (3,4,'bar')));

对于较旧版本的SQLite,使用带有UNION ALL的子查询(在版本3.15.1中进行了测试):

SELECT *
FROM table_name
WHERE (key1, key2, key3) IN (
  SELECT 1,2,'foo'
  UNION ALL
  SELECT 3,4,'bar'
);

或者,使用在任何版本中都可以工作的联接:

SELECT t.*
FROM table_name t
INNER JOIN (
  SELECT 1 key1, 2 key2, 'foo' key3
  UNION ALL
  SELECT 3,4,'bar'
) u ON u.key1 = t.key1 AND u.key2 = t.key2 AND u.key3 = t.key3;

请参阅demo

相关问题