Search code examples
androidcrashandroid-contentproviderandroid-sqlite

Android SQL crash - No such column


I have spent the last couple of days having this issue. I have read all of the similar questions on here as well as consulted numerous tutorials and even though everything looks right to me, my program still crashes.

Here is the the logcat:

08-02 15:13:41.876: D/ReminderProvider(1242): main oncreate called
08-02 15:13:41.984: I/dalvikvm(1242): threadid=3: reacting to signal 3
08-02 15:13:42.074: I/dalvikvm(1242): Wrote stack traces to '/data/anr/traces.txt'
08-02 15:13:42.234: D/ReminderListActivity(1242): onCreate
08-02 15:13:42.406: D/ReminderListActivity(1242): Displaying all the reminders in a list
08-02 15:13:42.474: I/dalvikvm(1242): threadid=3: reacting to signal 3
08-02 15:13:42.524: I/dalvikvm(1242): Wrote stack traces to '/data/anr/traces.txt'
08-02 15:13:42.804: D/gralloc_goldfish(1242): Emulator without GPU emulation detected.
08-02 15:13:43.234: D/ReminderProvider(1242): query
08-02 15:13:43.264: I/SqliteDatabaseCpp(1242): sqlite returned: error code = 1, msg = no such column: modified, db=/data/data/com.corsair.android.taskreminder/databases/reminders.db
08-02 15:13:43.274: W/dalvikvm(1242): threadid=11: thread exiting with uncaught exception (group=0x409c01f8)
08-02 15:13:43.374: E/AndroidRuntime(1242): FATAL EXCEPTION: AsyncTask #1
08-02 15:13:43.374: E/AndroidRuntime(1242): java.lang.RuntimeException: An error occured while executing doInBackground()
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.os.AsyncTask$3.done(AsyncTask.java:278)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at java.lang.Thread.run(Thread.java:856)
08-02 15:13:43.374: E/AndroidRuntime(1242): Caused by: android.database.sqlite.SQLiteException: no such column: modified: , while compiling: SELECT _id, title FROM reminders ORDER BY modified DESC
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:68)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.database.sqlite.SQLiteProgram.compileSql(SQLiteProgram.java:143)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.database.sqlite.SQLiteProgram.compileAndbindAllArgs(SQLiteProgram.java:361)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:127)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:94)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:53)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:47)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1564)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:354)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:291)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at com.corsair.android.taskreminder.ReminderListProvider.query(ReminderListProvider.java:133)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.content.ContentProvider$Transport.query(ContentProvider.java:178)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.content.ContentResolver.query(ContentResolver.java:311)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.content.CursorLoader.loadInBackground(CursorLoader.java:56)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.content.CursorLoader.loadInBackground(CursorLoader.java:42)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:255)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:66)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:55)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at android.os.AsyncTask$2.call(AsyncTask.java:264)
08-02 15:13:43.374: E/AndroidRuntime(1242):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)

So, it claims that I am trying to access columns that don't exist. Here is the bit from line 133 in my ReminderListProvider query method where it says the error is happening. Line 133 is the queryBuilder.query call:

// get the database and run the query
    SQLiteDatabase db = mOpenHelper.getReadableDatabase();
    Cursor cursor = queryBuilder.query(db, projection, selection,
            selectionArgs, null, null, orderby);

Here is the code where I declare my columns and create my database(I don't have a declaration for _id because my RemindersTableMetaData implements BaseColumns):

public static final String REMINDER_TITLE = "title";
public static final String REMINDER_BODY = "body";
public static final String REMINDER_DATE_TIME = "reminder_date_time";

    // script to create database
    public static final String DATABASE_CREATE_SCHEMA = "create table "
            + DATABASE_TABLE_NAME + " (" + RemindersTableMetaData._ID
            + " integer primary key autoincrement, " + REMINDER_TITLE
            + " text not null, " + REMINDER_BODY + " text not null, "
            + REMINDER_DATE_TIME + " text not null" + ");";

Here is the code that is called right before the query call:

String[] uiBindFrom = { RemindersTableMetaData._ID,
            RemindersTableMetaData.REMINDER_TITLE };
    int[] uiBindTo = { R.layout.layout_reminder_list };

    getLoaderManager().initLoader(REMINDER_LIST_LOADER, null, this);

    adapter = new SimpleCursorAdapter(this, R.layout.layout_reminder_row,
            null, uiBindFrom, uiBindTo, 0);

ISSUE SOLVED: Just to make it clear to anyone else who might run into this issue: What happened was I was confused on how the sortOrder argument to the method

@Override
public Cursor query(Uri uri, String[] projection, String selection,
        String[] selectionArgs, String sortOrder) {

was used. I thought that this was like a script command. For example you would pass in LOW_TO_HIGH or something and it would sort your results accordingly. Yes, I am an idiot sometimes. What you actually want to pass in here is a column name which will be used to sort the returned rows in the cursor. Anyway, I was passing in a string called "modified" which was NOT a declared column name and consequently, the program was crashing. I had been thinking it was something wrong with the way I was setting up my database, and all along it was this seemingly minor thing I had forgotten I had done. Such is life. Thanks to everyone for their help.


Solution

  • Just to make it clear to anyone else who might run into this issue: What happened was I was confused on how the sortOrder argument to the method

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
    

    was used. I thought that this was like a script command. For example you would pass in LOW_TO_HIGH or something and it would sort your results accordingly. Yes, I am an idiot sometimes. What you actually want to pass in here is a column name which will be used to sort the returned rows in the cursor. Anyway, I was passing in a string called "modified" which was NOT a declared column name and consequently, the program was crashing. I had been thinking it was something wrong with the way I was setting up my database, and all along it was this seemingly minor thing I had forgotten I had done. Such is life. Thanks to everyone for their help.