Указание ограничения/смещения для запросов ContentProvider

Я пытаюсь заставить ContentResolver запустить этот запрос:

select * from myTable limit 1 offset 2

В ContentResolver единственный метод запроса:

resolver.query(uri, projection, selection, selectionArgs, sortOrder);

Я пробовал:

final Cursor c = resolver.query(
        MyTable.CONTENT_URI,
        MyTable.PROJECTION,
        " ? ?",
        new String[] {"1", "2"},
        null);

Это просто выбрасывает исключение IllegaLArgumentException. Каков правильный способ достижения этого?

Ответы

Ответ 1

Я помещаю предложение LIMIT в параметр sordOrder, я также видел то же самое, что делали другие, но не уверен, что его 100% правильно:

final Cursor c = resolver.query(
        MyTable.CONTENT_URI,
        MyTable.PROJECTION,
        null,
        null,
        " limit 1 offset 2");

Ответ 2

Если вы предоставляете свой контент-провайдер, вы можете использовать android.net.Uri.Builder#appendQueryParameter для предоставления лимита и смещения в качестве параметров запроса, содержание которых провайдер может использовать при построении запроса.

public class MyProvider extends ContentProvider {
    public static final String QUERY_PARAMETER_LIMIT = "limit";
    public static final String QUERY_PARAMETER_OFFSET = "offset";

    public Cursor query(Uri uri, ...) {
        String limit = uri.getQueryParameter(QUERY_PARAMETER_LIMIT);
        String offset = uri.getQueryParameter(QUERY_PARAMETER_OFFSET);

        SQLiteQueryBuilder builder = new SQLiteQueryBuilder();

        // set the table name,...

        // leaving handling of null conditions as an exercise to the reader.
        String limitString = offset + "," + limit;

        Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder, limitString);

        //...

        return c;
    }
}

при построении запроса:

private static final Uri CONTENT_URI = MyProvider.CONTENT_URI.buildUpon()
        .appendQueryParameter(MyProvider.QUERY_PARAMETER_LIMIT,
                    String.valueOf(limit))
        .appendQueryParameter(MyProvider.QUERY_PARAMETER_OFFSET,
                    String.valueOf(offset))
        .build();

обратите внимание, что android.net.Uri.Builder#appendQueryParameter кодирует значение, чтобы предотвратить SQL-инъекцию.

Ссылки:

Ответ 3

Я помещаю предложение limit в качестве параметра запроса, используя синтаксис 'limit = offset, limit':

Cursor c = context.getContentResolver().query(
        MyTable.CONTENT_URI.buildUpon().encodedQuery("limit="+offset+","+limit).build(),
        MyTable.PROJECTION,
        null,
        null,
        null);

Он работает, по крайней мере, с помощью MediaStore uris. Будьте осторожны, не кодируя ",", или он не будет работать.

Ответ 4

Когда я попытался использовать предел String [см. предельную строку ниже], используя следующее:

 StringBuilder sbLimit = new StringBuilder().append(" ").append(i_offset).append(" , ").append(i_limit);
String limit = sbLimit .toString()

Это дало мне хорошие результаты в сочетании с выборами запросов, сортировкой и группировкой.