2011-02-15 59 views
4

我嘗試在自定義contentprovider上運行此查詢。Android - 在contentProvider中選擇max

cursor = activity.getContentResolver().query(
       GoalDescriptor.CONTENT_URI, 
       "max(priority)", null, 
       null, null); 

獲取優先級int列的最大值。

我也嘗試:

cursor = activity.getContentResolver().query(
       GoalDescriptor.CONTENT_URI, 
       null, "max(priority)", 
       null, null); 

絲毫沒有成功。

該代碼返回此異常:

java.lang.IllegalArgumentException: Invalid column MAX(priority) 
E/DatabaseUtils( 688):  at android.database.sqlite.SQLiteQueryBuilder.computeProjection(SQLiteQueryBuilder.java:523) 
E/DatabaseUtils( 688):  at android.database.sqlite.SQLiteQueryBuilder.buildQuery(SQLiteQueryBuilder.java:370) 
E/DatabaseUtils( 688):  at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:323) 
E/DatabaseUtils( 688):  at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:280) 
E/DatabaseUtils( 688):  at nan.salsa.contentprovider.goal.GoalContentProvider.query(GoalContentProvider.java:118) 
E/DatabaseUtils( 688):  at android.content.ContentProvider$Transport.bulkQuery(ContentProvider.java:150) 
E/DatabaseUtils( 688):  at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:111) 
E/DatabaseUtils( 688):  at android.os.Binder.execTransact(Binder.java:288) 
E/DatabaseUtils( 688):  at dalvik.system.NativeStart.run(Native Method) 
D/AndroidRuntime( 727): Shutting down VM 

我的內容提供者實現(標準 - 見記事本樣品)

public Cursor query(Uri uri, String[] projection, String selection, 
     String[] selectionArgs, String sortOrder) { 
    SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 
    qb.setTables(GoalDescriptor.TABLE_NAME); 

    switch (sUriMatcher.match(uri)) { 

    case GOAL: 
     qb.setProjectionMap(sGoalProjectionMap); 
     qb.appendWhere(GoalDescriptor._ID + "=" 
       + uri.getPathSegments().get(1)); 
     break; 

    case GOALS: 
     qb.setProjectionMap(sGoalProjectionMap); 
     break; 

    default: 
     throw new IllegalArgumentException("Unknown URI " + uri); 
    } 

    // If no sort order is specified use the default 
    String orderBy; 
    if (TextUtils.isEmpty(sortOrder)) { 
     orderBy = GoalInfo.GoalDescriptor.DEFAULT_SORT_ORDER; 
    } else { 
     orderBy = sortOrder; 
    } 

    // Get the database and run the query 
    SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 
    Cursor c = qb.query(db, projection, selection, selectionArgs, null, 
      null, orderBy); 

    // Tell the cursor what uri to watch, so it knows when its source data 
    // changes 
    c.setNotificationUri(getContext().getContentResolver(), uri); 
    return c; 
} 

你能幫助我嗎?

問候

+0

在MyTouch操作系統2.1(不知道SQLite的版本)上,我的語法對我有效,但在我的G2上失敗:( – mobibob 2011-04-22 06:09:16

回答

14

您發送的最大(優先級)的投影,在把它作爲選擇,它應該工作。

看到這個問題: Android: Get highest value in column

編輯:

看來這應該工作:

cursor = activity.getContentResolver().query(
     GoalDescriptor.CONTENT_URI, 
      new String[] {"MAX(priority) AS max_priority"}, null, 
     null, null); 
+1

我看到了,但這個解決方案對我來說不起作用... – 2011-02-15 17:04:43

1

遺憾的是NEX的回答(使用 「AS」,以提供列的別名)只與不在其SQLiteQueryBuilder中設置strictProjectionMap標誌的提供者一起工作。例如。聯繫人提供程序設置此標誌,因此如果您嘗試使用AS方法,則仍然會出現「無效列」錯誤。

如果有人能告訴我如何在選擇中指定像MAX這樣的聚合函數應該工作,我會非常感激。如果我嘗試它,我只會得到一個「濫用聚合函數」異常,這正是我期望嘗試將聚合函數放在WHERE子句中的結果。我知道你可以在WHERE子句中放置一個子查詢,但是假設你知道實際的表結構,並且它在任何給定的設備或操作系統級別都不會改變,我不想打賭(畢竟,這就是爲什麼首先使用提供者接口,從底層數據存儲抽象出來的原因)。

因此......我不知道有什麼辦法可以爲設置strictProjectionMap標誌的提供者執行此操作,而不是根據所需字段對DESC進行排序,並且如果提供程序支持,最好將LIMIT設置爲1行(或者if你願意通過在排序字符串中包含LIMIT來打破某些事情)。如果有人知道這些案例的其他方法,我會非常高興!

0

在我的情況下,nEx的答案確實有效,但我忘了在光標的getColumnIndexByName()方法中添加「max _」+ COLUMN_NAME。

我想通了之後,這也得到了改變,終於奏效了!