2010-05-18 104 views
1

您好,我有一個與Android SDK 1.6編程問題。我正在做「記事本實例」的相同內容,但是當我嘗試一些查詢時,程序崩潰。如果我嘗試直接在DatabaseHelper create()metod中執行查詢,它會執行,但是不在此函數中。你有什麼主意嗎?Android SQLite問題:嘗試查詢時程序崩潰!

這是源: public class DbAdapter {

public static final String KEY_NAME = "name"; 
public static final String KEY_TOT_DAYS = "totdays"; 
public static final String KEY_ROWID = "_id"; 

private static final String TAG = "DbAdapter"; 
private DatabaseHelper mDbHelper; 
private SQLiteDatabase mDb; 

private static final String DATABASE_NAME = "flowratedb"; 
private static final String DATABASE_TABLE = "girl_data"; 
private static final String DATABASE_TABLE_2 = "girl_cyle"; 
private static final int DATABASE_VERSION = 2; 
/** 
* Database creation sql statement 
*/ 
private static final String DATABASE_CREATE = 
     "create table "+DATABASE_TABLE+" (id integer, name text not null, totdays int);"; 
private static final String DATABASE_CREATE_2 = 
    "create table "+DATABASE_TABLE_2+" (ref_id integer, day long not null);"; 

private final Context mCtx; 

private static class DatabaseHelper extends SQLiteOpenHelper { 

    DatabaseHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.execSQL(DATABASE_CREATE); 
     db.execSQL(DATABASE_CREATE_2); 
     db.delete(DATABASE_TABLE, null, null); 
     db.delete(DATABASE_TABLE_2, null, null); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     Log.w(TAG, "Upgrading database from version " + oldVersion + " to " 
       + newVersion + ", which will destroy all old data"); 
     db.execSQL("DROP TABLE IF EXISTS "+DATABASE_TABLE); 
     db.execSQL("DROP TABLE IF EXISTS "+DATABASE_TABLE_2); 
     onCreate(db); 
    } 
} 
public DbAdapter(Context ctx) { 
    this.mCtx = ctx; 
} 
public DbAdapter open() throws SQLException { 
    mDbHelper = new DatabaseHelper(mCtx); 
    mDb = mDbHelper.getWritableDatabase(); 
    return this; 
} 
public void close() { 
    mDbHelper.close(); 
} 
public long createGirl(int id,String name, int totdays) { 
    ContentValues initialValues = new ContentValues(); 
    initialValues.put(KEY_ROWID, id); 
    initialValues.put(KEY_NAME, name); 
    initialValues.put(KEY_TOT_DAYS, totdays); 
    return mDb.insert(DATABASE_TABLE, null, initialValues); 
} 
public long createGirl_fd_day(int refid, long fd) { 
    ContentValues initialValues = new ContentValues(); 
    initialValues.put("ref_id", refid); 
    initialValues.put("calendar", fd); 
    return mDb.insert(DATABASE_TABLE, null, initialValues); 
} 
public boolean updateGirl(int rowId, String name, int totdays) { 
    ContentValues args = new ContentValues(); 
    args.put(KEY_NAME, name); 
    args.put(KEY_TOT_DAYS, totdays); 

    return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0; 
} 
public boolean deleteGirlsData() { 
    if (mDb.delete(DATABASE_TABLE_2, null, null)>0) 
     if(mDb.delete(DATABASE_TABLE, null, null)>0) 
      return true; 
    return false; 
} 
public Bundle fetchAllGirls() { 
    Bundle extras = new Bundle(); 
    Cursor cur = mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME, 
      KEY_TOT_DAYS}, null, null, null, null, null); 
    cur.moveToFirst(); 
    int tot = cur.getCount(); 
    extras.putInt("tot", tot); 
    int index; 
    for (int i=0;i<tot;i++){ 
     index=cur.getInt(cur.getColumnIndex("_id")); 
     extras.putString("name"+index, cur.getString(cur.getColumnIndex("name"))); 
     extras.putInt("totdays"+index, cur.getInt(cur.getColumnIndex("totdays"))); 
    } 
    cur.close(); 
    return extras; 
} 
public Cursor fetchGirl(int rowId) throws SQLException { 

    Cursor mCursor = 
      mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID, 
        KEY_NAME, KEY_TOT_DAYS}, KEY_ROWID + "=" + rowId, null, 
        null, null, null, null); 
    if (mCursor != null) { 
     mCursor.moveToFirst(); 
    } 
    return mCursor; 

} 
public Cursor fetchGirlCD(int rowId) throws SQLException { 

    Cursor mCursor = 
      mDb.query(true, DATABASE_TABLE_2, new String[] {"ref_id", 
        "day"}, "ref_id=" + rowId, null, 
        null, null, null, null); 
    if (mCursor != null) { 
     mCursor.moveToFirst(); 
    } 
    return mCursor; 

} 

}

坦克的 瓦萊里奧從意大利:)

+1

「程序崩潰」是什麼意思?請包括您的LogCat輸出。 – 2010-05-18 12:35:21

回答

1

我有同樣的問題,我解決了這個問題看你如何創建一個新的數據庫評論。

僅在創建數據庫時調用onCreate()方法。如果數據庫已全部創建完成(它會在您第一次嘗試代碼時創建:),則下次運行模擬器時不會調用onCreate。 所以修改onCreate()方法中的sql語句在下次啓動模擬器時不會更改表,並且您仍將擁有第一次啓動模擬器並創建數據庫時創建的表。在這種情況下,你的代碼中會出現錯誤的sql語句。 第二種情況是您使用了adb-sqlite3控制檯(shell)程序並修改了表。數據庫已經創建,所以onCreate()將不會被調用 - 無論您需要在onCreate()中描述表的哪個代碼,表格將與通過shell修改它的表相同...

我的問題是我刪除了使用shell的表,並期望onCreate重新創建它們,但數據庫已經創建,並且沒有表了。

所以,結論是第一次創建DATABASE時,所有的表都被創建了,如果你需要修改它們,通過shell修改它們或刪除數據庫,這樣onCreate就會被調用。程序。

天哪,這段文字聽起來像一個無限循環:) 遺憾的答案複雜,IM真的真的分層已經... :(

好運!

2

我還沒有機會尚未測試出我的理論,但它看起來像「DATABASE_CREATE」定義「ID 「,並且您在查詢中檢索」_id「。您最上面定義了「KEY_ROWID」,但不要在您的數據庫創建查詢中使用該常量。但是,如果這是你的主要問題,我不知道爲什麼「如果我試圖直接在DatabaseHelper create()metod中執行查詢,但它不會出現這個函數」。

希望有所幫助。

+0

我改正了KEY_ROWID的定義,但是prolem仍然存在。 注意:在DatabaseHelper的onCreate()方法中刪除(...),我把它們從這裏試試這個querys,它們不會崩潰,但在外面是的! – Skatephone 2010-05-18 13:56:35

+0

同意,我也看到了一些使用id列的不一致(你使用「id」來創建列,但使用「_id」來獲取和KEY_ROWID來獲取你的fetchAllGirls()中的值,這顯然會失敗cuz _id不是在你的光標)。我建議你爲所有PK id列使用常量'BaseColumns._ID'。在創建語句中將PK約束添加到此列,並且不要在創建時將其添加到ContentValues,讓SQLite爲您自動生成。 – 2010-05-18 14:55:30

+0

我解決了更改數據庫的名稱,可能是因爲有一些先例表。再見 – Skatephone 2010-05-26 15:28:11

0

通常,沒有太多的錯誤處理正在進行。有很多地方我可以看到代碼可能會崩潰。

對於初學者來說,圍繞這些東西的try-catch

  • parseInt函數()
  • 執行查詢,插入,更新,

另外:

  • 確保您的調用close()方法之前,mdb變量不爲null。
  • getcolumnIndex - 使用此的instad,按您想要的順序查詢您的記錄,然後您將知道每個字段在哪個索引中。例如:SELECT id,name from table然後您可以通過getString(1)訪問name;

最重要的是,請熟悉adb logcat(下面的鏈接)。該工具將從您的設備中提取日誌緩衝區並實時監控它,以查看崩潰情況。

如果您的應用程序崩潰,adb + logcat會顯示堆棧跟蹤,它將指向應用程序崩潰的確切位置,以及爲什麼!

https://developer.android.com/studio/command-line/adb.html#logcat

2

我有同樣的問題。即使讓所有的扭結出來的代碼後,查詢仍然崩潰。

我改變了DB名稱,它開始工作。

我懷疑,因爲我並沒有因爲時間重新啓動我的模擬器我測試過out ea更糟糕的代碼迭代,數據庫的一個實例在其中一個運行中被楔入。

相關問題