Search code examples
androiddatabasesqlitepragma

Cannot create Android SQLite database: PRAGMA error


Errors:

E/Database( 8614): Failure 21 (out of memory) on 0x0 when preparing 'PRAGMA user_version = 1'.
E/Database( 8614): Failure 21 (out of memory) on 0x0 when preparing 'ROLLBACK;'.
D/Database( 8614): exception during rollback, maybe the DB previously performed an auto-rollback
D/AndroidRuntime( 8614): Shutting down VM
W/dalvikvm( 8614): threadid=3: thread exiting with uncaught exception (group=0x4001dc20)
E/AndroidRuntime( 8614): Uncaught handler: thread main exiting due to uncaught exception

My current code:

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class Database extends SQLiteOpenHelper {

   private static String DatabaseName = "Entries.db"; 

   public Database(Context context) {
      super(context, DatabaseName, null, 1);
   }

   public void onCreate(SQLiteDatabase D) {
      D.execSQL(
            "CREATE TABLE Containers ("
            + "ID INTEGER PRIMARY KEY AUTOINCREMENT,"
            + "Parent INTEGER,"
            + "Sequence INTEGER,"
            + "Name TEXT"
            + ")"
      );
      D.execSQL(
            "CREATE TABLE Files ("
            + "ID INTEGER PRIMARY KEY AUTOINCREMENT,"
            + "Parent INTEGER,"
            + "Sequence INTEGER,"
            + "Name TEXT,"
            + "Text TEXT"
            + ")"
      );
      D.execSQL("INSERT INTO Containers (Parent, Sequence, Name) VALUES (0, 2, \"TestLine2\")");
      D.execSQL("INSERT INTO Containers (Parent, Sequence, Name) VALUES (0, 1, \"TestLine1\")");
      D.execSQL("INSERT INTO Containers (Parent, Sequence, Name) VALUES (0, 3, \"TestLine3\")");
      D.execSQL("INSERT INTO Containers (Parent, Sequence, Name) VALUES (2, 1, \"TestLine2-1\")");
      D.execSQL("INSERT INTO Containers (Parent, Sequence, Name) VALUES (2, 2, \"TestLine2-2\")");
      D.close();
   }

   @Override
   public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
   }

   public static Cursor Query(Context context, String SQL) {
      StartQuerySeries(context);
      Cursor Result = Query(SQL);
      StopQuerySeries();
      return Result;
   }

   private static Database D = null;
   public static void StartQuerySeries(Context context) {
      D = new Database(context);
   }
   public static Cursor Query(String SQL) {
      SQLiteDatabase X = D.getWritableDatabase();
      return X.rawQuery(SQL, null);
   }
   public static void StopQuerySeries() {
      D.close();
      D = null;
   }

}

The error happens when, in the primary Activity, it's called like this:

Database.Query(this, "INSERT INTO Files (Parent, Sequence, Name, Text) VALUES (1, 1, \"Item1\", \"Item1 Text\")");

The error happens on the "D.getWritableDatabase()" line... The closest thing I can find is, on http://www.sqlite.org/c3ref/c_abort.html that Failure 21 says "Library used incorrectly" - any help?

Oh, and I checked - the database file does get created, but there are no tables in it, so that onCreate() above isn't getting called.


Solution

  • I've got the same problem 2 minutes ago. I solved it by removing the D.close() line.

    It seems like android doesn't like it when you close the passed SQLiteDatabase Object. I think the surrounding code which calls the onCreate() method already manages opening and closing the database correctly. So you just have to do everything to get the tables up.

    Maybe There is some work done on this object after you created the tables. I would like to know if this solves your problem as well.

    I would also really love to hear the exact explaination for this behaviour.