2

我试图通过在ContentResolver的查询的选择字符串中定义 SQL WHERE子句来限制数据库结果。

Cursor cursor = getContentResolver().query(uri, null, getSelectionString(), null, null);

...

public String getSelectionString() {
    // TODO Replace latitude and longitude with database reference.
    StringBuilder string = new StringBuilder();
    string.append("latitude >= ").append(northEast.getLatitudeE6() / 1e6);
    string.append(" AND ");
    string.append("latitude <= ").append(southWest.getLatitudeE6() / 1e6);
    string.append(" AND ");
    string.append("longitude >= ").append(southWest.getLongitudeE6() / 1e6);
    string.append(" AND ");
    string.append("longitude <= ").append(northEast.getLongitudeE6() / 1e6);
    return string.toString();
}

数据库列定义如下...

public class CustomDatabase {
    public static final class Contract {
        public static final String COLUMN_NAME = "name";
        public static final String COLUMN_LATITUDE = "latitude";
        public static final String COLUMN_LONGITUDE = "longitude";
    }
}

...

我不是特别确定我可以检查游标中发送的查询。如果是这样,它不包含我发送的 WHERE 子句:

SQLiteQuery: SELECT * FROM custom_db ORDER BY number ASC

以下是选择字符串的示例:

latitude >= 48.203927 AND latitude <= 48.213851 AND longitude >= 16.36735 AND longitude <= 16.377648

问题:

  1. WHERE 子句在语法上是否正确?
  2. 我需要撇号吗?
  3. 我是否被迫在查询中一次使用两个参数(selection、selectionArgs)?
  4. 我在哪里可以调试整个查询?

编辑:

这是ContentProvider的query()方法...

public class CustomProvider extends ContentProvider {

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        switch (URI_MATCHER.match(uri)) {
        case URI_CODE_LOCATIONS:
            return mCustomDatabase.getLocations();
        }
        return null;
    }

...显然,正如biegleux猜测的那样,我忘了传递参数。嗬!
这是数据库方法的当前实现...

public class CustomSQLiteOpenHelper extends SQLiteOpenHelper {

    public Cursor getLocation() {
        return mDatabaseHelper.getReadableDatabase().query(
            CustomSQLiteOpenHelper.TABLE_NAME,
            null, null, null, null, null, null);
}

您是否建议我将方法签名更改为以下以传递所有参数?我不是以这种方式暴露了大部分数据库接口吗?

public Cursor getLocations(String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {
    return mDatabaseHelper.getReadableDatabase().query(
            CustomSQLiteOpenHelper.TABLE_NAME,
            columns, selection, selectionArgs, groupBy, having, orderBy);
}
4

2 回答 2

2

好的,看来query()您的提供商的方法正在引起问题。确保它看起来像下面这样。

@Override
public abstract Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
...

// run the query
db.query(db, projection, selection, selectionArgs, groupBy, having, sortOrder, limit);

您不必强制使用selectionArgs参数,但使用它的代码更具可读性。要调试查询,您可以使用

SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
Log.e(TAG, qb.buildQuery(projection, selection, selectionArgs, groupBy, having, sortOrder, limit);

编辑:如果您已ContentProvider实现,则无需公开getLocations()方法,因为您/用户可以使用ContentProvider's query()方法。您应该至少传递那些可以在query()方法中传递的参数,它们是projection,和.selectionselectionArgssortOrder

于 2012-07-14T14:37:25.217 回答
1

那条线不应该是:

Cursor cursor = getContentResolver().query(uri, null, getSelectionString(), null, null); 

请注意后面添加的括号getSelectionString,表示它是一个方法调用,而不是一个字符串(尽管我确实想知道为什么它不会引发错误,因为getSelectionString如果我的理论是正确的,它就不会作为字符串存在......)。

于 2012-07-14T13:27:17.723 回答