0

The following code snippet is supposed to remove duplicates from a SQLite table:

public int removeDuplicates(String table, String column, String idcolumn) {
    if (mDB.isReadOnly()) return -1;
    String idcol = idcolumn == null ? "_id" : idcolumn;
    String sql = String.format(Locale.US, "DELETE from %s where %s in " + "(select %s from %s JOIN "
            + "(select min(%s) as id_keep,%s,count(*) as dups from %s group by %s) AS A "
            + "ON A.%s=%s.%s where %s<>id_keep)", table, idcol, idcol, table, idcol, column, table, column, column,
            table, column, idcol);
    SQLiteStatement sqlcmd = mDB.compileStatement(sql);
    int result = sqlcmd.executeUpdateDelete();
    return result;
}

The problem is that a SQLiteReadOnlyDatabaseException gets thrown, even though it passes the !db.isReadOnly() test.

I don't think this problem is related to this question since everything is compiled against ICS; and other apps (using a ContentProvider driving the queries) are able to write to the DB.

The DB is in a public folder on the SD card.

The stack trace is:

11-02 14:48:24.596 E/AndroidRuntime(12324): android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a readonly database
11-02 14:48:24.596 E/AndroidRuntime(12324):     at android.database.sqlite.SQLiteStatement.native_executeSql(Native Method)
11-02 14:48:24.596 E/AndroidRuntime(12324):     at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:90)
11-02 14:48:24.596 E/AndroidRuntime(12324):     at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1899)
11-02 14:48:24.596 E/AndroidRuntime(12324):     at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1839)
11-02 14:48:24.596 E/AndroidRuntime(12324):     at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:661)
11-02 14:48:24.596 E/AndroidRuntime(12324):     at android.database.sqlite.SQLiteDatabase.beginTransactionNonExclusive(SQLiteDatabase.java:576)
11-02 14:48:24.596 E/AndroidRuntime(12324):     at android.database.sqlite.SQLiteStatement.acquireAndLock(SQLiteStatement.java:247)
11-02 14:48:24.596 E/AndroidRuntime(12324):     at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:84)
11-02 14:48:24.596 E/AndroidRuntime(12324):     at za.co.nimbus.druids.DatabaseTools.removeDuplicates(DatabaseTools.java:139)

Any ideas?

4
  • 4
    You stated the database is in a public folder on the SD card. Does your app have permission to write to the SD? <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> Commented Nov 2, 2012 at 12:59
  • Have you created your DB instance as writable like this : SQLiteDatabase database = this.getWritableDatabase(); Commented Nov 2, 2012 at 13:10
  • Son of a $%$@! @mah, you got it! I've been stuck on this for hours. Thanks. what a pity Android couldn't throw a more enlightening exception Commented Nov 2, 2012 at 14:38
  • I'm glad it helped. I've added my comment as an answer. Commented Nov 2, 2012 at 14:39

1 Answer 1

1

In order to write to a database that lives on SD, you'll need to have permission to write to external memory. Simply add the following to your manifest:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.