【问题标题】:How can I vaccuum an SQL database? My method for doing so is failing如何清理 SQL 数据库?我这样做的方法失败了
【发布时间】:2012-02-21 00:16:14
【问题描述】:

我有一个数据库,方法如下:

    public void deleteNote(long rowId) { 
    mDb.delete(DATABASE_TABLE, KEY_REALROWID + "=" + rowId, null); 
    int x = (int) rowId; 
    int y = testCount(); 
    while(x<y) 
    {x++; 
    Cursor note= fetchNote(x); 
    ContentValues argsan = new ContentValues(); 
    argsan.put(KEY_REALROWID, x-1); 
    long z = Integer.valueOf(note.getString
(note.getColumnIndexOrThrow(NotesDbAdapter.K EY_ROWID))); 
    mDb.update(DATABASE_TABLE, argsan, KEY_ROWID + "=" + z, null); 
                }} 

插入方法是这样的:

public void createNote(double value, String isroot, String ispower, 
String ismultiply, String isdivisor, String add, 
String issubtract, double roototpowerval, String 
paranthaseesend, String paranthaseesstart) { 
ContentValues initialValues = new ContentValues(); 
initialValues.put(KEY_VALUE, value); 
initialValues.put(KEY_ISROOT, isroot); 
initialValues.put(KEY_ISPOWER, ispower); 
initialValues.put(KEY_ISMULTIPLIER, ismultiply); 
initialValues.put(KEY_ISDIVISOR, isdivisor); 
initialValues.put(KEY_ISADD, add); 
initialValues.put(KEY_ISSUBTRACT, issubtract); 
initialValues.put(KEY_POWERORROOTNUMBER, roototpowerval); 
initialValues.put(KEY_REALROWID, testCount()+1); 
initialValues.put(KEY_ISPE, paranthaseesend); 
initialValues.put(KEY_ISPS, paranthaseesstart); 
mDb.insert(DATABASE_TABLE, null, initialValues); 
    } 

testCount() 方法是这样的:

public int testCount() {
     Cursor c = mDb.rawQuery("select count(*) from notes", null);
     int tst = 0;
     if (c.moveToNext()) {
         tst = c.getInt(c.getColumnIndex("count(*)"));
     }
     return tst;
    }

获取方法是这样的:

    public Cursor fetchNote(long rowId) throws SQLException { 
    Cursor mCursor = mDb.query(true, DATABASE_TABLE, new String[] 
    {KEY_ISPS,KEY_ISPE,KEY_VALUE, 
    KEY_ISROOT,KEY_REALROWID,KEY_ISPOWER,KEY_POWERORROOTNUMBER,KEY_ISDIVISOR,
KEY_ISMULTIPLIER, KEY_ISADD,KEY_ISSUBTRACT}, 
    KEY_REALROWID + "=" + rowId, null, null, null, null, null); 
    if (mCursor != null) { 
    mCursor.moveToFirst(); 
    } 
    return mCursor; 
        } 

当我运行它时,我得到一个错误:

    mDbHelper.createNote(d, "false", "false", "false", "false",
 "false", "false", 0, "false", "false"); 
    mDbHelper.createNote(0, "false", "false", "false","false",
 "false", "true", 0, "false", "false"); 
    mDbHelper.createNote(d, "false", "false", "false","false",
"false", "false", 0, "false", "false"); 
    mDbHelper.createNote(d, "false", "false", "false","false",
 "false", "false", 0, "false", "false"); 
    mDbHelper.deleteNote(3); 
    Cursor c = mDbHelper.fetchNote(3);

这是我的 LogCat:

FATAL EXCEPTION: main
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
at com.real.AlgebraActivity$1.onClick(AlgebraActivity.java:301)
at android.view.View.performClick(View.java:2485)
at android.view.View$PerformClick.run(View.java:9080)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3683)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)

一如既往地感谢您的帮助。

【问题讨论】:

  • 在我看来它失败了,因为您有一个空数据库。
  • 是的,错误是光标保持为空,但是如果您查看删除方法和我正在运行的方法,它应该在那里。
  • 您是否创建了可写数据库?我不确定您是否成功创建了数据库,您是否做过一些事情来验证它是否正确创建?
  • 是的,如果我不删除任何笔记,它会完美读写。
  • 您的testCount() 方法是如何工作的?

标签: android sql database vacuum


【解决方案1】:

好的,我想我找到了您的 Exception 的根源。 在活动onClick() 方法中,您创建(并在数据库中插入)4 个注释,删除一个(注释 3),然后获取注释 3(这应该是注释 4,已成为注释 3)。您没有通过该方法发布帖子的是其他行Cursor c = mDbHelper.fetchNote(3); 之后很可能您尝试使用该光标 c

问题是您的 deleteNote() 方法按照您的设计工作:
- 删除带有 id 的注释(在您的示例中为 3)
- x=3y 变为 3(您已从插入的 4 中删除了一行),因此当您进入 while 循环(x &lt; y)时,条件为假,因此您永远不会进入循环将注释 4 更新为注释 3。 现在您的数据库具有如下结构:

note 1
note 2
note 4

然后您尝试获取不存在的注释 3,最终得到一个空光标 c,您尝试在该光标上工作并抛出 CursorIndexOutOfBoundsException

要解决此问题,请尝试更新您的逻辑,以免在 KEY_REALROWID 列中出现空格。 (我还没有测试,但尝试将while(x &lt;= y) 放入deleteNote() 方法中)。
嗯,这就是我认为正在发生的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-09
    • 1970-01-01
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多