web-dev-qa-db-ja.com

SQLiteConstraintException:エラーコード19:制約に失敗しました-Androidエラー

私はこれについて他のいくつかの質問を見ましたが、答えのどれも私のコードでは実際には機能していないようでした。 DBに挿入しようとすると、「SQLiteConstraintException:エラーコード19:制約に失敗しました」というエラーが発生します。挿入操作のコードは次のとおりです。 db.insertは現在-1を返します。これにより、「挿入に失敗しました」というメッセージが表示されます。

関連するコンテンツプロバイダーコードは次のとおりです。

public static final String PROVIDER_NAME = "com.oliverapps.provider.DB";

public static final Uri CONTENT_URI = Uri.parse("content://"+ PROVIDER_NAME + "/tasks");

public static final String _ID = "_id";
public static final String CATEGORY = "category";
public static final String STORE = "store";
public static final String DESCRIPTION = "description";
public static final String DISTANCE = "distance";
public static final String CHECKED = "checked";

private static final int KEY_CATEGORY = 1;
private static final int KEY_STORE = 2;
private static final int KEY_DESCRIPTION = 3;
private static final int KEY_DISTANCE = 4;
private static final int KEY_CHECKED = 5;

private static final UriMatcher uriMatcher;
static{
    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    uriMatcher.addURI(PROVIDER_NAME, "category", KEY_CATEGORY);
    uriMatcher.addURI(PROVIDER_NAME, "category/store", KEY_STORE);
    uriMatcher.addURI(PROVIDER_NAME, "category/store/description", KEY_DESCRIPTION);
    uriMatcher.addURI(PROVIDER_NAME, "category/store/description/distance", KEY_DISTANCE);
    uriMatcher.addURI(PROVIDER_NAME, "checked", KEY_CHECKED);
}


//---for database use---
private SQLiteDatabase tasksDB;
private static final String DATABASE_NAME = "tasks";
private static final String DATABASE_TABLE = "tasks" +
        "";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE =
    "create table " + DATABASE_TABLE +
    " (" + _ID +  " integer primary key autoincrement, " +
    CATEGORY + " text not null, " + STORE + " text not null, " + DESCRIPTION + " text, " +
    DISTANCE + " text not null, " + CHECKED + " text not null);";

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);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
        Log.w("Content provider database", "Upgrading database from version " +
                oldVersion + " to " + newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
        onCreate(db);
    }
}


@Override
public Uri insert(Uri uri, ContentValues values){
    //---add a new task---
    long rowID = tasksDB.insert(DATABASE_TABLE, "", values);

    //---if added successfully---
    if(rowID > 0){
        Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
        getContext().getContentResolver().notifyChange(_uri, null);
        return _uri;
    }
    throw new SQLException("Failed to insert row into " + uri);
}

@Override
public boolean onCreate(){
    Context context = getContext();
    DatabaseHelper dbHelper = new DatabaseHelper(context);
    tasksDB = dbHelper.getWritableDatabase();
    return (tasksDB == null)? false:true;
}

Androidマニフェストからの関連コードは次のとおりです:

    <provider Android:name="DBProvider"
        Android:authorities="com.oliverapps.provider.DB" />

上記のinsertメソッドを呼び出す関連コードは次のとおりです。

ContentValues values = new ContentValues();
                values.put(DBProvider.CATEGORY, category);
                values.put(DBProvider.STORE, store);
                values.put(DBProvider.DESCRIPTION, description);
                values.put(DBProvider.DISTANCE, distance);

                Uri uri = getContentResolver().insert(DBProvider.CONTENT_URI, values);

これが機能しない理由はありますか?これは主に、私が持っているAndroidの本からのコードであり、自分のデータベースに変更されています。

16
Rebecca

一般的なエラーは次のとおりです。

  • nullではない制約がある列にnull値を挿入しようとしています(したがって、列定数の定義が間違っているために、値を設定できなかった可能性があります)。
  • 一意であると宣言されている列(通常の主キー列)に同じ値を挿入しています
  • 挿入に間違ったタイプの値を設定しました(たとえば、列はintegerですが、stringを設定します)

CHECKEDを設定するのを忘れたので、nullになり、not null制約。

42
Knickedi