SQLiteDatabase.query方法


121

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

我尝试了这个:

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

tableColumns-列参数的构造如下。

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

如果需要获取所有字段,那么应该如何构造column参数。我们是否需要在字符串数组中包括所有字段名称?

如何正确使用查询方法?


1
试着像一个简单的方法,
伊姆兰林蛙

我知道那个方法。但是我正在尝试学习如何实现查询方法而不是rawQuery。
sree_iphonedev,2012年

Answers:


244

tableColumns

  • null 对于所有列 SELECT * FROM ...
  • new String[] { "column1", "column2", ... }对于特定的列,例如SELECT column1, column2 FROM ...-您还可以在此处放置复杂的表达式:
    new String[] { "(SELECT max(column1) FROM table1) AS max" }将为您提供一列max,其中包含column1

条款

  • WHERE没有该关键字的部分,例如"column1 > 5"
  • 应该包括?动态的东西,例如"column1=?"-> seewhereArgs

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


限制/偏移量属于哪个...分组依据?有?订购?
Lion789 2014年

3
@ Lion789有几个带有limit参数的版本,例如developer.android.com/reference/android/database/sqlite/…最后都是简单的文本串联,因此您可以将eg "some_column LIMIT 10"放入其中orderBy,它仍然可以工作
zapl

这里有没有加入2张桌子的选项?
Vijay Kumbhoje

2
@VijayKumbhoje您应该可以将例如table1 CROSS JOIN table2作为表名。但是有一点我会看一下rawquery:stackoverflow.com/q/10598137/995891
zapl

3
@VijayKumbhoje无论您对什么感到更舒服/最终看起来都更干净。这些query方法仅向参数添加了诸如SELECT和的几个关键字(请参阅源代码),然后对结果查询字符串执行a 。如果您的查询不太适合的可用参数,请自己编写查询字符串。FROMrawQueryquery
zapl

21

这是一个更通用的答案,旨在为将来的观众快速参考。

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);

文档中的解释

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

16

where子句和args一起形成SQL查询的WHERE语句。所以说你想表达

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

然后您的whereClause和whereArgs将如下所示

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

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


不封闭?',在'必要时会自动添加
zapl

1

如果您的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);

0
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);

这是一个很好的数据库教程

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.