6

我正在尝试从数据库中选择一些数据,我有两段代码可以做到这一点:

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

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

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

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

SELECT col1, col2, col3 FROM SomeTables WHERE (id = '42')

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

SELECT col1, col2, col3 FROM SomeTables WHERE (id = 42)

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

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

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

CREATE TABLE SomeTable ( ID PRIMARY KEY, col1, col2, [...] )

UPD:顺便说一下,getSID(db) 返回字符串对象。

4

3 回答 3

8

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

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

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

于 2013-08-02T10:15:52.927 回答
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);

b) 从 selectionArgs:CAST(? as INTEGER)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);
于 2013-08-02T12:49:26.950 回答
0

您需要将int id转换为string,因为参数数组是字符串类型。例如:

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

它在第二种查询类型中起作用的原因是因为您将整数值附加到字符串中,该字符串会自动将 int 转换为 String。例如:

int i = 10;
String s = i + "";   //now 10 is in string
于 2013-08-02T09:57:39.430 回答