android sqlite 数据库约束
android sqlite database contraint
我有一个本地数据库来存储 moviedb.org api 提供的电影信息。每次代码都会将这些信息批量插入到我的本地数据库中,但我遇到了唯一约束错误。我知道是因为我将电影 ID 设置为唯一的,因为一开始我认为我必须避免重复相同的信息。
这是我的数据库代码:
public void onCreate(SQLiteDatabase db) {
final String SQL_CREATE_MOVIE_TABLE = "CREATE TABLE " + MovieContract.MovieEntry.TABLE_NAME + " (" +
MovieContract.MovieEntry._ID + " INTEGER PRIMARY KEY," +
MovieContract.MovieEntry.COLUMN_MOVIE_ID + " INTEGER UNIQUE NOT NULL, " +
MovieContract.MovieEntry.COLUMN_MOVIE_NAME + " TEXT NOT NULL, " +
MovieContract.MovieEntry.COLUMN_MOVIE_GENRE + " INTEGER NOT NULL, " +
MovieContract.MovieEntry.COLUMN_MOVIE_OVERVIEW + " TEXT NOT NULL, " +
MovieContract.MovieEntry.COLUMN_MOVIE_RELEASE_DATE + " TEXT NOT NULL, " +
MovieContract.MovieEntry.COLUMN_MOVIE_POSTER_PATH + " TEXT, " +
MovieContract.MovieEntry.COLUMN_MOVIE_POPULARITY + " DOUBLE NOT NULL, " +
MovieContract.MovieEntry.COLUMN_MOVIE_RATING + " DOUBLE NOT NULL " +
" );";
db.execSQL(SQL_CREATE_MOVIE_TABLE);
}
这是我的批量插入函数:
public int bulkInsert(Uri uri, ContentValues[] values) {
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
final int match = sUriMatcher.match(uri);
switch (match) {
case MOVIE:
db.beginTransaction();
int returnCount = 0;
try {
for (ContentValues value : values) {
long _id = db.insert(MovieContract.MovieEntry.TABLE_NAME, null, value);
if (_id != -1) {
returnCount++;
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
getContext().getContentResolver().notifyChange(uri, null);
return returnCount;
default:
return super.bulkInsert(uri, values);
}
}
所以,我想知道如果我去掉这个unique关键字,bulkinsert是否仍然会插入重复的信息,或者它会自动更新相同id的信息?如果不是,我应该怎么做才能确保 bulkinsert 在相同信息时不执行任何操作,如果 id 已经存在但其他相关信息已更改则更新。
谢谢
如果您只是删除 UNIQUE 约束并尝试批量插入数据,如果重复相同的项目,它将在您的数据库中重复。但是,您可以将插入方法调用替换为对 insertWithOnConflict
的调用
然后您可以决定如何准确处理重复项。默认是忽略 (CONFLICT_IGNORE)。您可能正在寻找 CONFLICT_REPLACE
When a UNIQUE constraint violation occurs, the pre-existing rows that
are causing the constraint violation are removed prior to inserting or
updating the current row. Thus the insert or update always occurs. The
command continues executing normally.
但可以根据您的要求使用 CONFLICT_IGNORE 或 CONFLICT_REPLACE。
我有一个本地数据库来存储 moviedb.org api 提供的电影信息。每次代码都会将这些信息批量插入到我的本地数据库中,但我遇到了唯一约束错误。我知道是因为我将电影 ID 设置为唯一的,因为一开始我认为我必须避免重复相同的信息。
这是我的数据库代码:
public void onCreate(SQLiteDatabase db) {
final String SQL_CREATE_MOVIE_TABLE = "CREATE TABLE " + MovieContract.MovieEntry.TABLE_NAME + " (" +
MovieContract.MovieEntry._ID + " INTEGER PRIMARY KEY," +
MovieContract.MovieEntry.COLUMN_MOVIE_ID + " INTEGER UNIQUE NOT NULL, " +
MovieContract.MovieEntry.COLUMN_MOVIE_NAME + " TEXT NOT NULL, " +
MovieContract.MovieEntry.COLUMN_MOVIE_GENRE + " INTEGER NOT NULL, " +
MovieContract.MovieEntry.COLUMN_MOVIE_OVERVIEW + " TEXT NOT NULL, " +
MovieContract.MovieEntry.COLUMN_MOVIE_RELEASE_DATE + " TEXT NOT NULL, " +
MovieContract.MovieEntry.COLUMN_MOVIE_POSTER_PATH + " TEXT, " +
MovieContract.MovieEntry.COLUMN_MOVIE_POPULARITY + " DOUBLE NOT NULL, " +
MovieContract.MovieEntry.COLUMN_MOVIE_RATING + " DOUBLE NOT NULL " +
" );";
db.execSQL(SQL_CREATE_MOVIE_TABLE);
}
这是我的批量插入函数:
public int bulkInsert(Uri uri, ContentValues[] values) {
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
final int match = sUriMatcher.match(uri);
switch (match) {
case MOVIE:
db.beginTransaction();
int returnCount = 0;
try {
for (ContentValues value : values) {
long _id = db.insert(MovieContract.MovieEntry.TABLE_NAME, null, value);
if (_id != -1) {
returnCount++;
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
getContext().getContentResolver().notifyChange(uri, null);
return returnCount;
default:
return super.bulkInsert(uri, values);
}
}
所以,我想知道如果我去掉这个unique关键字,bulkinsert是否仍然会插入重复的信息,或者它会自动更新相同id的信息?如果不是,我应该怎么做才能确保 bulkinsert 在相同信息时不执行任何操作,如果 id 已经存在但其他相关信息已更改则更新。 谢谢
如果您只是删除 UNIQUE 约束并尝试批量插入数据,如果重复相同的项目,它将在您的数据库中重复。但是,您可以将插入方法调用替换为对 insertWithOnConflict
的调用然后您可以决定如何准确处理重复项。默认是忽略 (CONFLICT_IGNORE)。您可能正在寻找 CONFLICT_REPLACE
When a UNIQUE constraint violation occurs, the pre-existing rows that are causing the constraint violation are removed prior to inserting or updating the current row. Thus the insert or update always occurs. The command continues executing normally.
但可以根据您的要求使用 CONFLICT_IGNORE 或 CONFLICT_REPLACE。