2012-03-05 2 views
2

Не понимаю, почему запрос заканчивается бросанием NullPointerException.SQLite INNER JOIN бросает NullPointerException

В моей базе данных две таблицы. Первый, который называется TABLE_WORDS, содержит слова; второй - TABLE_TRANS содержит переводы. Одно слово может иметь много переводов.

public static final String CREATE_TABLE_WORDS = "CREATE TABLE " + TABLE_WORDS + 
    " (" + WORDS_ID + " INTEGER PRIMARY KEY, " + WORDS_WORD + 
    " TEXT);"; 

public static final String CREATE_TABLE_TRANS = "CREATE TABLE " + TABLE_TRANS + 
    " (" + TRANS_ID + " INTEGER PRIMARY KEY, " + 
    TRANS_WORD + " TEXT, " + 
    TRANS_FOREIGN_ID_WORD + " INTEGER, " + 
    "FOREIGN KEY (" + TRANS_FOREIGN_ID_WORD + ") REFERENCES " + TABLE_WORDS + "(" + WORDS_ID + "));"; 

я запрашиваю переводы на слово ID, и NPE отбрасывается.

public Cursor queryTransesByWord(int idSend) { 

    String query = "SELECT " + DbHelper.TABLE_WORDS + "." + DbHelper.WORDS_WORD + ", " + 
     DbHelper.TABLE_TRANS + "." + DbHelper.TRANS_WORD + 
     " FROM " + DbHelper.TABLE_WORDS + 
     " INNER JOIN " + DbHelper.TABLE_TRANS + 
     " ON " + DbHelper.TABLE_WORDS + "." + DbHelper.WORDS_ID + "=" + 
     DbHelper.TABLE_TRANS + "." + DbHelper.TRANS_FOREIGN_ID_WORD + " WHERE " + 
     DbHelper.TABLE_WORDS + "." + DbHelper.WORDS_ID + "="+ idSend; 

    Cursor cur = db.rawQuery(query, null); // NullPointer always throws here 

    if (cur != null) 
     cur.moveToFirst(); 
    else 
     Log.e(Constants.LOG_TAG, Constants.DB_ADAPTER_CLASS_NAME_SEP + "queryTransesByWord cursor is null"); 
    return cur; 
} 

ответ

4

Ну, учитывая код:

Cursor cur = db.rawQuery(query, null); // NullPointer always throws here 

Это говорит о том, что db является недействительным. В этом выражении нет другой операции разыменования - так что, если трассировка стека фактически показывает rawQuery в ней где-то, то db равно null. Вы не дали каких-либо указаний о том, где db призван быть присвоен ненулевое значение, но это первое, что нужно проверить ...

Как и в сторону, пожалуйста не содержат значений в SQL вот так - это рецепт для SQL injection attacks. Вместо этого используйте параметризованный SQL.

+0

дб не был пустым, я gorgot, чтобы открыть его перед запросом. public class DbAdapter { \t частный помощник DbHelper; \t частный SQLiteDatabase db; \t private int openStatus; общественного недействительными openForReading() { \t \t, если (openStatus == 0) { \t \t \t дБ = helper.getReadableDatabase(); \t \t \t openStatus = 1; \t \t} // если (openStatus == 0) \t \t еще \t \t \t, если (openStatus == 2) { \t \t \t \t helper.close(); \t \t \t \t db = helper.getReadableDatabase(); \t \t \t} // вложенными, если (openStatus == 2) \t \t \t \t Log.i (Constants.LOG_TAG, Constants.DB_ADAPTER_CLASS_NAME_SEP + "openForReading успеха"); \t} –

+0

@RedPlanet: В этом случае линия, которую вы показали, не была бы в верхней части трассировки стека. (Вот почему вы должны были включить трассировку стека в свой вопрос.) Но похоже, что если вы не назвали 'openForReading', тогда' db' * будет * быть null ... –

1

В моем случае я должен использовать

String query = "SELECT " + DbHelper.TABLE_WORDS + "." + DbHelper.WORDS_WORD + ", " + 
    DbHelper.TABLE_TRANS + "." + DbHelper.TRANS_WORD + 
    " FROM " + DbHelper.TABLE_WORDS + 
    " INNER JOIN " + DbHelper.TABLE_TRANS + 
    " ON " + DbHelper.TABLE_WORDS + "." + DbHelper.WORDS_ID + "=" + 
    DbHelper.TABLE_TRANS + "." + DbHelper.TRANS_FOREIGN_ID_WORD + " WHERE " + 
    DbHelper.TABLE_WORDS + "." + DbHelper.WORDS_ID + "=?";  

Cursor cur = db.rawQuery(query, new String[] { Integer.toString(idSend) }); 

я прав?

1
String query = "SELECT " + DbHelper.TABLE_WORDS + "." + DbHelper.WORDS_WORD + ", " + 
DbHelper.TABLE_TRANS + "." + DbHelper.TRANS_WORD + 
" FROM " + DbHelper.TABLE_WORDS + 
" INNER JOIN " + DbHelper.TABLE_TRANS + 
" ON " + DbHelper.TABLE_WORDS + "." + DbHelper.WORDS_ID + "=" + 
DbHelper.TABLE_TRANS + "." + DbHelper.TRANS_FOREIGN_ID_WORD + " WHERE " + 
DbHelper.TABLE_WORDS + "." + DbHelper.WORDS_ID + "=?";  

Cursor cur = db.rawQuery(query, new String[] { Integer.toString(idSend) }); 

это работает для меня :-)