【问题标题】:Issue in accessing database in Android, Table isn't getting created在 Android 中访问数据库时出现问题,未创建表
【发布时间】:2013-08-02 11:38:38
【问题描述】:

似乎数据库已创建,但当我尝试访问已创建的数据库时出现错误。每当调用 doQuery() 时,应用程序就会崩溃。你能帮我弄清楚我做错了什么吗?

private class LoadCursorTask extends AsyncTask<Void, Void, Void>
   {
        Cursor constantCursor=null;     

    @Override       
    protected Void doInBackground(Void... params)
    {

        // TODO Auto-generated method stub
        Log.d("Action1","in doInBacground()"); 
        constantCursor=doQuery(); 
        Log.d("Action1","after doQuery ");
        constantCursor.getCount(); 

        return null;
    }


}


private Cursor doQuery() 
{

    Log.d("Action1","in doQuery()");
    Cursor localCursor= db.getReadableDatabase().rawQuery("SELECT _id,  title, value"+" FROM constants ORDER BY title; ", null);
    Log.d("Action1","before returning from doQuery()"); 
    return localCursor; 
}

stacktrack 上的错误报告如下所示:

08-02 11:23:31.012: E/SQLiteLog(1829): (1) no such table: constants
08-02 11:23:31.040: W/dalvikvm(1829): threadid=11: thread exiting with uncaught exception (group=0x40a71930)
08-02 11:23:31.173: E/AndroidRuntime(1829): FATAL EXCEPTION: AsyncTask #1
08-02 11:23:31.173: E/AndroidRuntime(1829): java.lang.RuntimeException: An error occured while executing doInBackground()
08-02 11:23:31.173: E/AndroidRuntime(1829):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at java.util.concurrent.FutureTask.run(FutureTask.java:239)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at java.lang.Thread.run(Thread.java:856)
08-02 11:23:31.173: E/AndroidRuntime(1829): Caused by: android.database.sqlite.SQLiteException: no such table: constants (code 1): , while compiling: SELECT _id,  title, value FROM constants ORDER BY title;
08-02 11:23:31.173: E/AndroidRuntime(1829):     at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:882)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:493)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at com.example.database_constants.ConstantsFragment.doQuery(ConstantsFragment.java:28)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at com.example.database_constants.ConstantsFragment.access$0(ConstantsFragment.java:25)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at com.example.database_constants.ConstantsFragment$LoadCursorTask.doInBackground(ConstantsFragment.java:47)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at com.example.database_constants.ConstantsFragment$LoadCursorTask.doInBackground(ConstantsFragment.java:1)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
08-02 11:23:31.173: E/AndroidRuntime(1829):     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
08-02 11:23:31.173: E/AndroidRuntime(1829):     ... 4 more

这是我创建数据库的方式:

db.execSQL("CREATE TABLE constants (_id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, value REAL);");

[更新 1] 这是DatabaseHelper.class

public class DatabaseHelper extends SQLiteOpenHelper
{
    private static final String DATABASE_NAME="constants.db";
  private static final int SCHEMA=1; 
  static final String TITLE="title"; 
  static final String VALUE="value"; 
  static final String TABLE="constants";


public DatabaseHelper(Context context) {
    super(context, DATABASE_NAME, null, SCHEMA);
    // TODO Auto-generated constructor stub
    Log.d("Action1","in DatabaseHelper constructor"); 
}

@Override
public void onCreate(SQLiteDatabase db)
{
    Log.d("Action1","in onCreate");
    try
    {
        db.beginTransaction();
        db.execSQL("CREATE TABLE constants (_id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, value REAL)");

        ContentValues cv=new ContentValues(); 

        cv.put(TITLE, "Gravity, Death Star I"); 
        cv.put(VALUE, SensorManager.GRAVITY_DEATH_STAR_I); 
        db.insert("constants", TITLE, cv);

        cv.put(TITLE, "Gravity, Earth"); 
        cv.put(VALUE, SensorManager.GRAVITY_EARTH); 
        db.insert("constants", TITLE, cv); 

        cv.put(TITLE, "Gravity, Jupiter"); 
        cv.put(VALUE, SensorManager.GRAVITY_JUPITER); 
            db.insert("constants", TITLE, cv); 
    }
        finally
    {

        db.endTransaction(); 
    }

}
}

【问题讨论】:

  • Uhm....“引起:android.database.sqlite.SQLiteException:没有这样的表:常量(代码1)”
  • 没有这样的表:常量。创建常量表
  • 删除“;”在您的数据库中创建行。
  • 创建数据库的数据库助手类的邮政编码。
  • 那么,db.execSQL(.. 部分是否曾在其他代码之前运行过?

标签: android runtime-error android-sqlite sqliteopenhelper


【解决方案1】:

它可能没有找到您的数据库文件,并在您尝试打开它时创建了一个新的空文件。检查数据库的名称和位置。如果您在代码中创建它,请确保在尝试访问它之前创建表。

编辑:

发现你的问题,你需要在endTransaction之前将事务标记为成功,否则它会被回滚。

@Override
public void onCreate(SQLiteDatabase db)
{
    Log.d("Action1","in onCreate");
    try
    {
        db.beginTransaction();
        db.execSQL("CREATE TABLE constants (_id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, value REAL)");

        ContentValues cv=new ContentValues(); 

        cv.put(TITLE, "Gravity, Death Star I"); 
        cv.put(VALUE, SensorManager.GRAVITY_DEATH_STAR_I); 
        db.insert("constants", TITLE, cv);

        cv.put(TITLE, "Gravity, Earth"); 
        cv.put(VALUE, SensorManager.GRAVITY_EARTH); 
        db.insert("constants", TITLE, cv); 

        cv.put(TITLE, "Gravity, Jupiter"); 
        cv.put(VALUE, SensorManager.GRAVITY_JUPITER); 
        db.insert("constants", TITLE, cv);
        db.setTransactionSuccessful();
    }
        finally
    {

        db.endTransaction(); 
    }

}

Source

【讨论】:

  • 好的,所以我检查数据库是否是通过 DDMS 文件资源管理器创建的,是的,数据库文件在那里。但是,在检查数据库时,似乎没有创建表。所以正如你所说的那样存在问题。对不起,如果我听起来很天真,但我似乎无法弄清楚为什么没有创建表。你能帮帮我吗? :\
  • 在使用 endTransaction 之前使用 db.setTransactionSuccessful()。编辑答案。
  • 最后。现在就像一个魅力。非常感谢:)
  • 请注意,onCreate() 已经在事务中运行,因此启动嵌套事务不会增加任何好处,只会增加代码大小和复杂性。
  • 正确,根据SQLiteOpenHelper documentation。所以我们可以省去begingTransactionendTransaction
猜你喜欢
  • 2015-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多