2013-10-03 2 views
2

저는 sqlite, LocationsContentProvider를 사용하여 Android 애플리케이션을 개발 중입니다. JOIN에 문제가 있습니다.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

'아무 것도 전송되지 않는 것 같습니다'라는 메시지가 표시되면 오류가 발생하지 않고 단순히 쿼리가 데이터를 반환하지 않는다고 생각합니까?

이 경우 데이터에 문제가있을 수 있습니다. sub_map_id가 NULL 인 '위치'의 모든 행은 조인에 실패하고 반환되지 않습니다. 마찬가지로, sub_map_id가 _id의 항목과 일치하지 않는 행은 sub_map_table에 리턴되지 않습니다.

INNER JOIN 대신 LEFT JOIN을 사용하면 '위치'에서 모든 행을 가져옵니다. 그러나 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

감사합니다. 실제로 문제를 제시 한 내부 결합이었습니다. LEFT JOIN으로 변경 했으므로 제대로 작동합니다. INNER JOIN의 출력이 비어 있습니다. 그러나 a.id AS a_id를 사용하면 오류가 발생합니다. "열 '_id'는 존재하지 않습니다. 그대로 두어야할지 생각하고 있습니다. – Julien

+0

아 물론 물론 어댑터에서 커서를 사용하는 경우 in. 안에 "_id"라는 열이 있어야합니다. 따라서 b._id에서 AS를 사용하는 것이 좋습니다. – NigelK

관련 문제