0

所以最近,我问了一个关于我创建的扩展 SQLiteOpenHelper 的类的问题,其中的insert()语句导致 Logcat 中的错误。最近,我决定使用 ddms 来提取我的应用程序应该充当接口的数据库,然后在终端中查看它。结果是这样的:

图为:我正在查看最近提取的应用程序数据库版本 令我惊讶的是,我只看到一个插入语句(无论如何来自我的应用程序)。我在我的应用程序中尝试了多次插入,只有最初的“Hello world!” 让它进来。

我不确定问题是什么。谁能帮我弄清楚为什么我的数据库只是自重?我的猜测涉及主键没有正确增加,但我不知道为什么会这样。此外,Logcat 中不再出现错误。

我已经包含了我班级中的构造函数,以防它们可能会有所帮助。此外,我还包括了自上一个问题以来我对 getNewTaskId() 所做的更改:

public NagTasksDatabaseHelper(Context context, String name,
        CursorFactory factory, int version) {
    super(context, name, factory, version);
    // TODO Auto-generated constructor stub
}

/*
public NagTasksDatabaseHelper(Context context, String name,
        CursorFactory factory, int version,
        DatabaseErrorHandler errorHandler) {
    super(context, name, factory, version, errorHandler);
    // TODO Auto-generated constructor stub
    // NOTE TO SELF: Do not use this constructor. DatabaseErrorHandler only exists in Honeycomb onward.
}
*/
public NagTasksDatabaseHelper(Context context, CursorFactory factory){
    super(context, "NagTasks", factory, 1);
}
public NagTasksDatabaseHelper(Context context) //Most frequently use constructor
{
    super(context, "NagTasks", null, 1);
}
public int getNewTaskId(SQLiteDatabase db)
{
    Cursor c = db.rawQuery("SELECT MAX(_id) FROM TASKS", null);
    c.moveToFirst();
    int columnID = c.getColumnIndex(ID);
    if (columnID == -1)
    {
        c.close();
        return 0;
    } else {
        int newTaskID = c.getInt(columnID) +1;
        c.close();
        return newTaskID;
    }
}
public void addTask(String title, String notes)
{
    SQLiteDatabase db = getWritableDatabase();
    int newestID = getNewTaskId(db);
    ContentValues values = new ContentValues();
    values.put("_id", newestID);
    values.put("TASK", title);
    values.put("NOTE", notes);
    values.put("ISCHECKED", 0);
    db.insert("TASKS", null, values);
    db.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE IF NOT EXISTS TASKS (_id INTEGER PRIMARY KEY, TASK TEXT, NOTE TEXT, ISCHECKED INTEGER);");
}

编辑:我将这些getColumnIndex()行更改为getColumnIndexorThrow()并在 LogCat 中得到这些错误:

06-17 18:47:40.557: V/LoaderManager(329): onLoadComplete: LoaderInfo{44f2ac00 #854 : SQLiteCursorLoader{44f2b950}}
06-17 18:47:40.557: V/LoaderManager(329):   onLoadFinished in SQLiteCursorLoader{44f2b950 id=854}: SQLiteCursor{44ee0800}
06-17 18:47:51.887: D/AndroidRuntime(329): Shutting down VM
06-17 18:47:51.887: W/dalvikvm(329): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
06-17 18:47:51.907: E/AndroidRuntime(329): FATAL EXCEPTION: main
06-17 18:47:51.907: E/AndroidRuntime(329): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mowdownDevelopments.nagTasks/com.mowdownDevelopments.nagTasks.NagTasksAddTasksActivity}: java.lang.IllegalArgumentException: column '_id' does not exist
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.app.ActivityThread.access$2300(ActivityThread.java:125)
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.os.Handler.dispatchMessage(Handler.java:99)
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.os.Looper.loop(Looper.java:123)
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.app.ActivityThread.main(ActivityThread.java:4627)
06-17 18:47:51.907: E/AndroidRuntime(329):  at java.lang.reflect.Method.invokeNative(Native Method)
06-17 18:47:51.907: E/AndroidRuntime(329):  at java.lang.reflect.Method.invoke(Method.java:521)
06-17 18:47:51.907: E/AndroidRuntime(329):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
06-17 18:47:51.907: E/AndroidRuntime(329):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
06-17 18:47:51.907: E/AndroidRuntime(329):  at dalvik.system.NativeStart.main(Native Method)
06-17 18:47:51.907: E/AndroidRuntime(329): Caused by: java.lang.IllegalArgumentException: column '_id' does not exist
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:314)
06-17 18:47:51.907: E/AndroidRuntime(329):  at com.mowdownDevelopments.nagTasks.NagTasksDatabaseHelper.getNewTaskId(NagTasksDatabaseHelper.java:127)
06-17 18:47:51.907: E/AndroidRuntime(329):  at com.mowdownDevelopments.nagTasks.NagTasksDatabaseHelper.getNewTaskId(NagTasksDatabaseHelper.java:141)
06-17 18:47:51.907: E/AndroidRuntime(329):  at com.mowdownDevelopments.nagTasks.NagTasksAddTaskFragment.onActivityCreated(NagTasksAddTaskFragment.java:42)
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:891)
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080)
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1810)
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:501)
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1129)
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.app.Activity.performStart(Activity.java:3781)
06-17 18:47:51.907: E/AndroidRuntime(329):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2636)
06-17 18:47:51.907: E/AndroidRuntime(329):  ... 11 more
06-17 18:47:58.947: I/Process(329): Sending signal. PID: 329 SIG: 9

...那么,“_id”怎么会不存在呢?它将解释旧版本如何总是通过 0。

4

3 回答 3

1

我的猜测涉及主键没有正确增加,但我不知道为什么会这样。

所以你_id不是自动递增的,因为你没有指定它是递增的。所以onCreate用这个替换你的方法:

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE TASKS (_id INTEGER PRIMARY KEY AUTOINCREMENT, TASK TEXT, NOTE TEXT, ISCHECKED INTEGER);");
}

您必须AUTOINCREMENT为您的_id.

您没有在插入数据的位置添加代码,但您应该使用insert()这种SQLiteDatabase结合ContentValues.

public boolean addNewData(String name, String address) {
   ContentValues data = new ContentValues();
   data.put("NameColumn", name);
   data.put("AddressColumn", address);
   db.insert("TASKS", "NameColumn", data);
}

你也应该调用in或close()方法的方法。只需在此处添加更多代码片段或整个实现即可。SQLiteonStoponDestroy


编辑:

getNewTask 示例

public int getNewTask(SQLiteDatabase db) {
        String SELECT_QUERY = "SELECT MAX(_id) FROM TASKS";
        Cursor c = db.rawQuery(SELECT_QUERY, null);
        if (c.getCount() > 0) {
            c.moveToFirst();
            int i = c.getInt(0);
            if (i > 0) {
                return i;
            }   
            else {
                return 0;
            }
        }
        else {
            return 0;
        }
    }
于 2012-06-14T20:31:40.933 回答
0

那不应该是

int columnID = c.getColumnIndex("_id"); // not ID

你总是得到 0 的回报getNewTaskId

于 2012-06-15T02:34:34.880 回答
0

所以,事实证明问题实际上是传递给的列名getColumnIndex()实际上是不存在的。因此,简单的解决方法是将别名分配给MAX(_id)...

public int getNewTaskId(SQLiteDatabase db)
{
    Cursor c = db.rawQuery("SELECT MAX(_id) AS max FROM TASKS", null);
    c.moveToFirst();
    int columnID = c.getColumnIndex("max");
    if (columnID == -1)
    {
        c.close();
        return 0;
    } else {
        int newTaskID = c.getInt(columnID) +1;
        c.close();
        return newTaskID;
    }
}

这解决了这个问题。

于 2012-06-17T20:22:44.187 回答