SQLiteQueryBuilder中的selectionArgs不适用于列中的整数值

unc*_*Lem 6 sql sqlite android android-sqlite

我正在尝试从数据库中选择一些数据,我有两片代码来做:

cursor = builder.query(db,
                    new String[]{"col1", "col2", "col3"},
                    "id = ?", new String[]{getSID(db)}, null, null, null);
Run Code Online (Sandbox Code Playgroud)

cursor = builder.query(db,
                    new String[]{"col1", "col2", "col3"},
                    "id = " + getSID(db), null, null, null, null);
Run Code Online (Sandbox Code Playgroud)

它们之间的区别在于,根据文档,第一个似乎更正确,但它也不起作用 - 光标是空的.而不是第二个 - 我得到了我需要的所有数据.

所以我尝试在我的电脑上使用数据库副本执行不同的SQL查询,这就是我所拥有的:

SELECT col1, col2, col3 FROM SomeTables WHERE (id = '42')
Run Code Online (Sandbox Code Playgroud)

这个不起作用(这个查询显然等于查询,由第一个代码示例生成)

SELECT col1, col2, col3 FROM SomeTables WHERE (id = 42)
Run Code Online (Sandbox Code Playgroud)

这个工作正常(等于从第二个代码示例查询).

据我所知,SQLite应该自动执行类型转换,但出了点问题,我不知道为什么.您对如何修复第一个代码示例有什么想法吗?(或者,也许,数据库?)

如果重要的话,这里是CREATE带有id字段的表的简化脚本:

CREATE TABLE SomeTable ( ID PRIMARY KEY, col1, col2, [...] )
Run Code Online (Sandbox Code Playgroud)

UPD:顺便说一下,getSID(db)返回String Object.

CL.*_*CL. 8

那个查询参数只能是字符串,这是Android数据库API中一个可怕的设计错误.

尽管文档说的是,但您应该仅将参数用于实际的字符串值; 整数值可以安全地直接嵌入到SQL字符串中.(对于blob,您必须使用接受的函数ContentValues.)

请注意,虽然SQLite使用动态类型,但在大多数情况下(返回),不同类型的值不会相等.在某些情况下,SQLite 类型亲和性而自动转换值(在您的情况下,如果您将列声明为,则会发生这种情况),但这是违反直觉的,因此不应该依赖它.SELECT 42='42';0idINTEGER

  • 找到它:`CAST(?作为INTEGER)`工作正常.它看起来更像是肮脏的黑客,但它确实有效. (2认同)

unc*_*Lem 2

根据 SQLite文档

SQLite 版本 3 数据库中的任何列(除 INTEGER PRIMARY KEY 列外)都可用于存储任何存储类的值。

就我而言,这意味着我们无法确定列中将存储什么数据类型。如果您可以在将数据放入数据库时​​控制和转换数据类型 - 您可以在将数据添加到数据库时转换id值并轻松使用。但这不是我问题的答案,因为我必须按原样处理数据库内容。TEXTselectionArgs

因此,可能的解决方案:

a) 将整数值嵌入selection字符串中,而不将它们包装到'

cursor = builder.query(db,
                    new String[]{"col1", "col2", "col3"},
                    "id = " + getSID(db), null, null, null, null);
Run Code Online (Sandbox Code Playgroud)

CAST(? as INTEGER)b) 从 SelectionArgs:或 中转换值CAST(id AS TEXT)。我认为,将列转换为TEXT是更好的解决方案,因为右操作数始终是TEXT,但左操作数可以是任何东西。所以:

cursor = builder.query(db,
                    new String[]{"col1", "col2", "col3"},
                    "CAST(id AS TEXT) = ?", 
                    new String[]{getSID(db)}, null, null, null);
Run Code Online (Sandbox Code Playgroud)