开发者

SQLite Problem: Program Crash When Try a Query

I have a problem programming with Android SDK 1.6. I'm doing the same things of the "notepad example" but the program crash when I try some query. If I try to do a query directly in to the DatabaseHelper create() method it goes, but out of this function it doesn't. Do you have any idea?

This is the source:

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;

    }
}


I haven't had a chance to test out my theory yet, but it looks like "DATABASE_CREATE" defines "id", and you're retrieving "_id" in your queries. You define "KEY_ROWID" up top, but don't use that constant in your DB creation query.

However, if this was your main problem, I dont't know why "If i try to do a query directly in to the DatabaseHelper create() metod it goes, but out of this function it doesn't".

Hope that helps.


I had the same problem. Even after getting all the kinks out of the code, the query was still crashing.

I changed the DB name and it started working.

I suspect that since I had not restarted my emulator since the time I had tested out earlier iterations of 'bad' code, that an instance of the DB became wedged in one of the runs.


i had the same problem, i solved it looking at your comment about creating a new database.

The onCreate() method is called only when creating the database. If database is allready created (it creates the first time you try the code :), onCreate will not be called the next time you run the emulator. so modifying the sql statement in onCreate() method wont change the table the next time you start the emulator, and you will still have the table that was created the first time you started your emulator and created the database. with this scenario you will have faulty sql statements in you code. second scenario is that you used the adb-sqlite3 console (shell) program and modified the table(s). Database is already created, so onCreate() wont be called - and no matter what code you have to describe the table in you onCreate() the table will be the same as you modified it through shell...

my problem was that i deleted the tables using shell, and expected onCreate to re-create them, but the database was already created, and had no tables anymore.

So, the conclusion is that the first time you create the DATABASE all the tables are created, and if you need to modify them, modify them through shell or delete the database so the onCreate will be called nes time you run your program.

gosh, this text sounds like a infinite loop :) sorry for complicating the answer, im realy realy tiered already... :(

good luck!


In general, there's not much error handling going on. There are a number of places I can see the code might crash.

For starters, surround these things with try-catch

  • parseInt()
  • Performing queries, inserts, updates,

Also:

  • Make sure your mDB variable isn't null before calling its close() method.
  • getcolumnIndex - instad of using this, query your records in the order you want, then you will know what index each field is in. for example: SELECT id,name from table then you can access name with getString(1);

And most importantly of all, familiarize yourself with the adb logcat (link below). This tool will extract the log buffer from your device AND monitor it in real time, for crashes.

If your app crashes, adb+logcat will show you the stack trace, which will point to the exact line where your app crashed, and why!

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜