关于SQLiteConstraintException错误代码19,我该怎么办?

时间:2012-06-05 22:12:45

标签: android sql error-handling constraints

我该如何处理错误代码19?我发布了LogCat,我的DatabaseAdapter(RemindersDbAdapter)和RemindersEditActivity的一些代码,我认为这会引起问题(第316-336行)

这是我的LogCat:

06-05 23:57:53.607: E/AndroidRuntime(549): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
06-05 23:57:53.607: E/AndroidRuntime(549):  at android.database.sqlite.SQLiteStatement.native_execute(Native Method)
06-05 23:57:53.607: E/AndroidRuntime(549):  at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:92)
06-05 23:57:53.607: E/AndroidRuntime(549):  at android.database.sqlite.SQLiteDatabase.updateWithOnConflict(SQLiteDatabase.java:1810)
06-05 23:57:53.607: E/AndroidRuntime(549):  at android.database.sqlite.SQLiteDatabase.update(SQLiteDatabase.java:1761)
06-05 23:57:53.607: E/AndroidRuntime(549):  at com.xyz.android.taskreminder.RemindersDbAdapter.updateReminder(RemindersDbAdapter.java:204)
06-05 23:57:53.607: E/AndroidRuntime(549):  at com.xyz.android.taskreminder.ReminderEditActivity.saveState(ReminderEditActivity.java:333)
06-05 23:57:53.607: E/AndroidRuntime(549):  at com.xyz.android.taskreminder.ReminderEditActivity.access$0(ReminderEditActivity.java:316)
06-05 23:57:53.607: E/AndroidRuntime(549):  at com.xyz.android.taskreminder.ReminderEditActivity$3.onClick(ReminderEditActivity.java:161)
06-05 23:57:53.607: E/AndroidRuntime(549):  at android.view.View.performClick(View.java:3511)
06-05 23:57:53.607: E/AndroidRuntime(549):  at android.view.View$PerformClick.run(View.java:14105)
06-05 23:57:53.607: E/AndroidRuntime(549):  at android.os.Handler.handleCallback(Handler.java:605)
06-05 23:57:53.607: E/AndroidRuntime(549):  at android.os.Handler.dispatchMessage(Handler.java:92)
06-05 23:57:53.607: E/AndroidRuntime(549):  at android.os.Looper.loop(Looper.java:137)
06-05 23:57:53.607: E/AndroidRuntime(549):  at android.app.ActivityThread.main(ActivityThread.java:4424)
06-05 23:57:53.607: E/AndroidRuntime(549):  at java.lang.reflect.Method.invokeNative(Native Method)
06-05 23:57:53.607: E/AndroidRuntime(549):  at java.lang.reflect.Method.invoke(Method.java:511)
06-05 23:57:53.607: E/AndroidRuntime(549):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
06-05 23:57:53.607: E/AndroidRuntime(549):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
06-05 23:57:53.607: E/AndroidRuntime(549):  at dalvik.system.NativeStart.main(Native Method)

这是我的DatabaseAdapter:

public class RemindersDbAdapter {

//
// Databsae Related Constants
//
private static final String DATABASE_NAME = "data";
private static final String DATABASE_TABLE = "reminders";
private static final int DATABASE_VERSION = 10;

public static final String KEY_TITLE = "title";
public static final String KEY_BODY = "body";
public static final String KEY_IMAGE = "image";
public static final String KEY_DATE_TIME = "reminder_date_time"; 
public static final String KEY_ROWID = "_id";


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

/**
 * Database creation SQL statement
 */
private static final String DATABASE_CREATE =
        "create table " + DATABASE_TABLE + " ("
                + KEY_ROWID + " integer primary key autoincrement, "
                + KEY_TITLE + " text not null, " 
                + KEY_BODY + " text not null, " 
                + KEY_IMAGE + " text not null, "
                + KEY_DATE_TIME + " text 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("PRAGMA foreign_keys = OFF;");
    }

    @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);
        onCreate(db);
    }
}

/**
 * Constructor - takes the context to allow the database to be
 * opened/created
 * 
 * @param ctx the Context within which to work
 */
public RemindersDbAdapter(Context ctx) {
    this.mCtx = ctx;
}

public RemindersDbAdapter open() throws SQLException {
    mDbHelper = new DatabaseHelper(mCtx);
    mDb = mDbHelper.getWritableDatabase();
    return this;
}

public void close() {
    mDbHelper.close();
}


public long createReminder(String title, String body, String path, String reminderDateTime) {
    ContentValues initialValues = new ContentValues();
    initialValues.put(KEY_TITLE, title);
    initialValues.put(KEY_BODY, body);
    initialValues.put(KEY_IMAGE, path);   
    initialValues.put(KEY_DATE_TIME, reminderDateTime); 

    return mDb.insert(DATABASE_TABLE, null, initialValues);
}

public boolean deleteReminder(long rowId) {

    return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}


public Cursor fetchAllReminders() {

    return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_TITLE,
            KEY_BODY, KEY_IMAGE, KEY_DATE_TIME}, null, null, null, null, null);
}


public Cursor fetchReminder(long rowId) throws SQLException {

    Cursor mCursor =

            mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
                    KEY_TITLE, KEY_BODY, KEY_IMAGE, KEY_DATE_TIME}, KEY_ROWID + "=" + rowId, null,
                    null, null, null, null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;

}

// Fetches a single image
public Cursor fetchImage(long rowId) throws SQLException {

    Cursor mCursor =

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

}



public boolean updateReminder(long rowId, String title, String body, String path, String reminderDateTime) {
    ContentValues args = new ContentValues();
    args.put(KEY_TITLE, title);
    args.put(KEY_BODY, body);
    args.put(KEY_IMAGE, path);
    args.put(KEY_DATE_TIME, reminderDateTime);

    return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}

}

这是我的RemindersEditActivity的第316-336行:

//
// Saves the content by communicating with the RemindersDbAdapter.
//
private void saveState() {
    String title = mTitleText.getText().toString();
    String body = mBodyText.getText().toString();

    String path = (String)mImageView.getTag();

    SimpleDateFormat dateTimeFormat = new SimpleDateFormat(DATE_TIME_FORMAT);
    String reminderDateTime = dateTimeFormat.format(mCalendar.getTime());

    // Creates a new reminder if the value is null.
    if (mRowId == null) {
        long id = mDbHelper.createReminder(title, body, path, reminderDateTime);
        if (id > 0) {
            mRowId = id;
        } 
    // Updates the reminder if the content is not null.     
    } else {
        mDbHelper.updateReminder(mRowId, title, body, path, reminderDateTime);

    }
}

1 个答案:

答案 0 :(得分:0)

嗯,你唯一的约束是“not null”,所以不要插入一个空值的列。

它来自您的更新,因此请使用调试器检查所有进入null的参数。

您的其他选项当然是删除非空约束(需要更新/重新创建数据库)。