2013-10-03 2 views
2

Я работаю над Android-приложением с sqlite, LocationsContentProvider. У меня проблемы с 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

Есть ли ошибки в вашем логарифме? Если это недопустимый запрос, SQLite скажет вам об этом. Если нет, у вашего запроса может быть только 0 результатов, и мы не могли бы ответить вам, не зная данные и структуру базы данных. –

+0

Является ли 'DATABASE_TABLE' =' "местоположениями' '? И каждый 'FIELD_' * соответствует' 'a._' *' ''? –

ответ

2

От «ничего, кажется, не отправлено через», я полагаю, что вы не испытываете ошибку, и просто, что ваш запрос не возвращает данные?

Если это так, то проблема может быть связана с вашими данными. Любые строки в 'location', где sub_map_id IS NULL будут терпеть неудачу, и не будут возвращены. Аналогично, любые строки, в которых sub_map_id не имеет соответствующей записи _id в sub_map_table, не возвращаются.

Если вы используете 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» внутри. Поэтому я предлагаю просто использовать AS на b._id. – NigelK

Смежные вопросы