SQLiteDatabase.query 方法

Posted

技术标签:

【中文标题】SQLiteDatabase.query 方法【英文标题】:SQLiteDatabase.query method 【发布时间】:2012-05-22 23:03:45 【问题描述】:

我使用的是SQLiteDatabase的查询方法。如何使用查询方法?

我试过了:

Cursor cursor = sqLiteDatabase.query(
    tableName, tableColumns, whereClause, whereArgs, groupBy, having, orderBy);

tableColumns - 列参数构造如下。

String[] columns = new String[]KEY_ID, KEY_CONTENT;

如果我们需要获取所有的字段,列参数应该如何构造。我们需要在字符串数组中包含所有字段名称吗?

如何正确使用查询方式?

【问题讨论】:

试试this这样的简单方法 我知道那种方法。但我正在尝试学习如何实现查询方法而不是 rawQuery。 【参考方案1】:

表格列

null 用于所有列,如 SELECT * FROM ... new String[] "column1", "column2", ... 用于 SELECT column1, column2 FROM ... 中的特定列 - 您也可以在此处放置复杂的表达式:new String[] "(SELECT max(column1) FROM table1) AS max" 将为您提供一个名为 max 的列,其中包含 column1 的最大值

where子句

你放在WHERE 之后没有那个关键字的部分,例如"column1 > 5" 应该包含? 用于动态的事物,例如"column1=?" -> 见whereArgs

whereArgs

指定在whereClause 中按出现顺序填充每个? 的内容

其他人

就像whereClause关键字后面的语句或null,如果你不使用它。

示例

String[] tableColumns = new String[] 
    "column1",
    "(SELECT max(column1) FROM table2) AS max"
;
String whereClause = "column1 = ? OR column1 = ?";
String[] whereArgs = new String[] 
    "value1",
    "value2"
;
String orderBy = "column1";
Cursor c = sqLiteDatabase.query("table1", tableColumns, whereClause, whereArgs,
        null, null, orderBy);

// since we have a named column we can do
int idx = c.getColumnIndex("max");

相当于下面的原始查询

String queryString =
    "SELECT column1, (SELECT max(column1) FROM table1) AS max FROM table1 " +
    "WHERE column1 = ? OR column1 = ? ORDER BY column1";
sqLiteDatabase.rawQuery(queryString, whereArgs);

通过使用 Where/Bind -Args 版本,您可以自动获得转义值,并且您不必担心输入数据是否包含 '

不安全:String whereClause = "column1='" + value + "'"; 保险箱:String whereClause = "column1=?";

因为如果 value 包含 ' 您的语句要么中断并且您得到异常或执行意外的事情,例如 value = "XYZ'; DROP TABLE table1;--" 甚至可能删除您的表,因为该语句将变成两个语句和一个注释:

SELECT * FROM table1 where column1='XYZ'; DROP TABLE table1;--'

使用 args 版本 XYZ'; DROP TABLE table1;-- 将被转义为 'XYZ''; DROP TABLE table1;--' 并且只会被视为一个值。即使' 不是为了做坏事,人们在他们的名字中使用它或在文本、文件名、密码等中使用它仍然很常见。所以请始终使用 args 版本。 (虽然可以将int 和其他原语直接构建到whereClause 中)

【讨论】:

Limit/offset 在这个... group by 中属于哪里?有? orderby? @Lion789 有几个版本具有limit 参数,例如developer.android.com/reference/android/database/sqlite/… 最后只是简单的文本连接,因此您可以输入例如"some_column LIMIT 10"orderBy 仍然可以工作 这里可以选择加入 2 个表吗? @VijayKumbhoje 你应该可以放例如table1 CROSS JOIN table2 作为表名。但有一点我会看 rawquery:***.com/q/10598137/995891 @VijayKumbhoje 无论你觉得更舒服/最终看起来更干净。 query 方法只是在参数(see source) 中添加一些关键字,如@9​​87654358@ 和FROM,然后使用生成的查询字符串执行rawQuery。如果您的查询不适合query 的可用参数,请自己编写查询字符串。【参考方案2】:

这是一个更笼统的答案,旨在为未来的观众提供快速参考。

示例

SQLiteDatabase db = helper.getReadableDatabase();

String table = "table2";
String[] columns = "column1", "column3";
String selection = "column3 =?";
String[] selectionArgs = "apple";
String groupBy = null;
String having = null;
String orderBy = "column3 DESC";
String limit = "10";

Cursor cursor = db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit);

来自documentation的解释

table String: 编译查询的表名。 columns String:要返回的列的列表。传递 null 将返回所有列,不鼓励这样做以防止读取数据 来自不会被使用的存储空间。 selection String:一个过滤器,声明要返回哪些行,格式化为 SQL WHERE 子句(不包括 WHERE 本身)。通过 null 将返回给定表的所有行。 selectionArgs String:您可以在选择中包含 ?s,它将被 selectionArgs 中的值替换,以便它们 出现在选择中。这些值将绑定为字符串。 groupBy 字符串:声明如何对行进行分组的过滤器,格式化为 SQL GROUP BY 子句(不包括 GROUP BY 本身)。传递空值 将导致行不被分组。 having 字符串:一个过滤器声明哪些行组包含在游标中,如果正在使用行分组,格式化为 SQL HAVING 子句(不包括 HAVING 本身)。传递 null 将导致所有行 要包括的组,并且在不进行行分组时是必需的 用过。 orderBy String:如何对行进行排序,格式化为 SQL ORDER BY 子句(不包括 ORDER BY 本身)。传递 null 将使用 默认排序顺序,可能是无序的。 limit String:限制查询返回的行数,格式为 LIMIT 子句。传递 null 表示没有 LIMIT 子句。

【讨论】:

【参考方案3】:

Where 子句和 args 共同构成 SQL 查询的 WHERE 语句。所以说你想表达

WHERE Column1 = 'value1' AND Column2 = 'value2'

那么你的 whereClause 和 whereArgs 将如下所示

String whereClause = "Column1 =? AND Column2 =?";
String[] whereArgs = new String[]"value1", "value2";

如果您想选择所有表格列,我相信传递给 tableColumns 的空字符串就足够了。

【讨论】:

不要将?包含在'中,如果需要,'会自动添加【参考方案4】:

如果你的 SQL 查询是这样的

SELECT col-1, col-2 FROM tableName WHERE col-1=apple,col-2=mango
GROUPBY col-3 HAVING Count(col-4) > 5  ORDERBY col-2 DESC LIMIT 15;

那么对于 query() 方法,我们可以这样做:-

String table = "tableName";
String[] columns = "col-1", "col-2";
String selection = "col-1 =? AND col-2=?";       
String[] selectionArgs = "apple","mango";
String groupBy =col-3;
String having =" COUNT(col-4) > 5";
String orderBy = "col-2 DESC";
String limit = "15";

query(tableName, columns, selection, selectionArgs, groupBy, having, orderBy, limit);

【讨论】:

【参考方案5】:
db.query(
        TABLE_NAME,
        new String[]  TABLE_ROW_ID, TABLE_ROW_ONE, TABLE_ROW_TWO ,
        TABLE_ROW_ID + "=" + rowID,
        null, null, null, null, null
);

TABLE_ROW_ID + "=" + rowID,这里的=where 子句。要选择所有值,您必须提供所有列名:

or you can use a raw query like this 
db.rawQuery("SELECT * FROM permissions_table WHERE name = 'Comics' ", null);

这是一个good tutorial 用于数据库。

【讨论】:

以上是关于SQLiteDatabase.query 方法的主要内容,如果未能解决你的问题,请参考以下文章

在 SQLiteDatabase.query() 中使用 String[] selectionArgs

sq优化的几种方法(转)

matlab里sq啥意思

解决一点乱码问题的方法

void create_sq(sqlist &sq,int n)在数据结构中的含义

sqlist中的sq代表啥意思