2013-10-03 67 views
2

我正在使用sqlite LocationsContentProvider處理Android應用程序。 我在加入時遇到了一些麻煩。Android sqlite JOIN不顯示數據

這是工作的罰款:

// Returns all the locations from the table 
    public Cursor getAllLocations(){    
     Cursor cursor; 
     cursor = mDB.query(DATABASE_TABLE, new String[] { FIELD_ROW_ID, FIELD_LAT , FIELD_LNG, FIELD_ZOOM, FIELD_ADDRESS } , null, null, null, null, null); 
     Log.d(TAG, "DB: query complete" + cursor); 
     return cursor; 
    } 

,這是不工作:

// Return all locations joined with sub map name 
    public Cursor getAllLocations(){ 
     Cursor cursor; 
     String query; 
     query = "SELECT a._id, a.lat, a.lng, a.sub_map_id, a.zoom, a.address, b._id, b.sub_map FROM locations a" + 
       " INNER JOIN sub_map_table b ON a.sub_map_id=b._id"; 
     Log.d(TAG, "DB: query = \n" + query; 
     Log.d(TAG, "DB: query complete"); 
     cursor = mDB.rawQuery(query, null); 
     return cursor; 
    } 

數據庫結構的一些其他細節:

// Fields for locations table 
public static final String FIELD_ROW_ID ="_id"; 
public static final String FIELD_LAT = "lat"; 
public static final String FIELD_LNG = "lng"; 
public static final String FIELD_ZOOM = "zoom"; 
public static final String FIELD_ADDRESS ="address"; 
public static final String FIELD_SUB_MAP_ID = "sub_map_id"; 

// Fields for SUB_MAP_TABLE table 
public static final String FIELD_SUB_MAP_ROW_ID = "_id"; 
public static final String FIELD_SUB_MAP = "sub_map"; 

//table name, a constant 
private static final String DATABASE_TABLE = "locations"; 
private static final String SUB_MAP_TABLE = "sub_map_table"; 

private static final String TAG = null; 

//instance variable for SQLiteDatabse 
private SQLiteDatabase mDB; 

//constructor 
public LocationsDB(Context context) { 
    super(context, DBNAME, null, VERSION); 
    this.mDB = getWritableDatabase(); 
} 

/** This is a callback method, invoked when the method getReadableDatabase()/getWritableDatabase() is called 
    * provided the database does not exists 
    * */ 
    @Override 
    public void onCreate(SQLiteDatabase db) { 
     String create_table_locations =  "create table " + DATABASE_TABLE + " (" + 
             FIELD_ROW_ID + " integer primary key autoincrement , " + 
             FIELD_LNG + " double , " + 
             FIELD_LAT + " double , " + 
             FIELD_ZOOM + " text , " + 
             FIELD_ADDRESS + " text , " + 
             FIELD_SUB_MAP_ID + " integer " + 
             ") "; 

     String create_table_submap = "create table " + SUB_MAP_TABLE + " (" + 
            FIELD_SUB_MAP_ROW_ID + " integer primary key autoincrement , " + 
            FIELD_SUB_MAP + " text " + 
            ") "; 

     db.execSQL(create_table_locations); 
     db.execSQL(create_table_submap); 

一直在研究這個的整整一天,我無法弄清楚什麼是錯的。請建議我。 似乎沒有什麼東西被傳送過來?或者如果它被髮送,它不會被捕獲。

+1

您的logcat中是否存在一些錯誤?如果這是一個無效的查詢,SQLite會告訴你。如果沒有,您的查詢可能只有0個結果,如果不知道您的數據庫數據和結構,我們無法回答您。 –

+0

DATABASE_TABLE' ='「locations」'?每個'FIELD_' *匹配'「a._' *'」'? –

回答

2

通過「似乎沒有發送通過」,我認爲你沒有遇到錯誤,只是你的查詢返回沒有數據?

如果是這種情況,那麼問題可能與您的數據有關。 'location'中的任何行sub_map_id IS NULL都會使連接失敗並且不會返回。同樣,sub_map_id在sub_map_table中沒有_id的匹配條目的任何行都不會被返回。

如果您使用LEFT JOIN而不是INNER JOIN,那麼您將從'location'中獲得所有行。但是,如果連接到sub_map_table失敗,則爲b._id和b.sub_map返回的值將爲NULL。

此外,您的結果集中有重複的列名,即a._id和b._id都將返回列名'_id',如果您嘗試從遊標引用它們將導致問題。您可以使用AS來區分它們並在結果中給它們一個唯一的名稱,例如:

SELECT a._id AS a_id, b._id AS b_id 
+0

感謝提示,我會嘗試一下。 – Julien

+1

非常感謝這是INNER JOIN提出的問題。我已經把它改成了LEFT JOIN,它工作正常。 INNER JOIN輸出爲空。然而,使用a.id AS a_id會給我一個錯誤,「column'_id'不存在,我試圖弄清楚我是否應該保持它的原樣 – Julien

+0

啊,當然,如果你在適配器中使用光標,它的內部必須有一個名爲「_id」的列。所以我建議在b._id上使用AS。 – NigelK