在Android使用Sqlite時,《Head First Android 開發》裏就提到,一定要有"_id"列,一般平常建表都會把 _id 列建上,但是就不一定會讀取出來。多次都沒出錯,所以沒覺得這有啥重要的。直到有一次對多表進行聯合查詢時,麻煩纔出現。
有2個表:
public static final String C_MONTHDETAIL = "create table monthdetail(_id integer primary key autoincrement," +
"sId integer," +
"mId integer," +
"mPrice float," +
"mDetail text)";
public static final String C_SHARENAME = "create table sharename(_id integer primary key autoincrement," +
"sName text," +
"sCode text)";
現在要讀出mPrice和sName,這兩個表sId和sharename的_id是一致的。
String rawsql="SELECT monthdetail.mPrice,monthdetail.mDetail,sharename.sName FROM monthdetail INNER JOIN sharename ON monthdetail.sId=sharename._id WHERE monthdetail.mId=?";
cursor_dList=sqLiteDatabase.rawQuery(rawsql,new String[]{String.valueOf(dataID)});
SimpleCursorAdapter simpleCursorAdapter=new SimpleCursorAdapter(MainActivity.this,R.layout.main_detaillist,cursor_dList,
new String[]{"sharename.sName","monthdetail.mPrice"},new int[]{R.id.main_sharename,R.id.main_mPrice},0);
detailList.setAdapter(simpleCursorAdapter);
其中dataID是當需查詢的mId值。
結果Activity報錯:
java.lang.IllegalArgumentException: column '_id' does not exist
百度了一下,發現正是因爲使用INNER JOIN聯合查詢時,表內不存在 _id 列所導致的。有些大神使用AS重新命名一列可以解決問題。於是修改了一下代碼:
String rawsql="SELECT monthdetail.mPrice,monthdetail.mDetail,sharename.sName,monthdetail._id as _id FROM monthdetail INNER JOIN sharename ON monthdetail.sId=sharename._id WHERE monthdetail.mId=?";
cursor_dList=sqLiteDatabase.rawQuery(rawsql,new String[]{String.valueOf(dataID)});
SimpleCursorAdapter simpleCursorAdapter=new SimpleCursorAdapter(MainActivity.this,R.layout.main_detaillist,cursor_dList,
new String[]{"sharename.sName","monthdetail.mPrice"},new int[]{R.id.main_sharename,R.id.main_mPrice},0);
detailList.setAdapter(simpleCursorAdapter);
把monthdetail裏的_id列讀取出來,使用 as _id,變爲_id 列,因爲其在本表也是無重複的,所以跟普通的_id 列屬性一致。重新編譯,ListView的detailList就可以正常顯示了。