Android SQLite Columns … are not unique

匿名 (未验证) 提交于 2019-12-03 09:05:37

问题:

I am using SQLite on android and am getting this error

02-11 18:05:37.224: E/SQLiteDatabase(26583): android.database.sqlite.SQLiteConstraintException: columns name, foreign_word are not unique (code 19) 

However, this is called right after onUpgrade() is called, so there should be nothing in the database itself. This is the SQL Statement used :

private static final String CREATE_DB_TB_2 = "CREATE TABLE "         + TABLE_VOCAB_WORDS + "(" + COLUMN_NAME + " TEXT NOT NULL,"         + COLUMN_WORD_FOREIGN + " TEXT NOT NULL," + COLUMN_WORD_ENGLISH         + " TEXT NOT NULL," + COLUMN_CORRECT         + " BYTE NOT NULL, PRIMARY KEY (" + COLUMN_NAME + ","         + COLUMN_WORD_FOREIGN + "))"; 

As there is nothing in the database as I drop the table, why am I getting the error when I add something?? Furthermore, I am calling context.deleteDatabase(NAME); every time I run the app. The thing must be unique as the table is empty !

Thanks in advance

Full LogCat:

02-11 18:38:02.811: E/SQLiteDatabase(28631): Error inserting correct=0 english_meaning= tener prisa foreign_word=to be in a hurry  name=AQA GCSE Spanish Higher 02-11 18:38:02.811: E/SQLiteDatabase(28631): android.database.sqlite.SQLiteConstraintException: columns name, foreign_word are not unique (code 19) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:775) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1525) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1395) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at com.sharma.gcsevocabtester.DatabaseManipulator.addWord(DatabaseManipulator.java:168) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at com.sharma.gcsevocabtester.DatabaseManipulator$ImportVocabList.onPostExecute(DatabaseManipulator.java:420) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at com.sharma.gcsevocabtester.DatabaseManipulator$ImportVocabList.onPostExecute(DatabaseManipulator.java:1) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at android.os.AsyncTask.finish(AsyncTask.java:631) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at android.os.AsyncTask.access$600(AsyncTask.java:177) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at android.os.Handler.dispatchMessage(Handler.java:99) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at android.os.Looper.loop(Looper.java:155) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at android.app.ActivityThread.main(ActivityThread.java:5454) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at java.lang.reflect.Method.invokeNative(Native Method) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at java.lang.reflect.Method.invoke(Method.java:511) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:796) 02-11 18:38:02.811: E/SQLiteDatabase(28631):    at dalvik.system.NativeStart.main(Native Method) 

Furthermore, I'm not sure if this will make a difference but I also have another table which is created using this String.

private static final String CREATE_DB_TB_1 = "CREATE TABLE "         + TABLE_VOCAB_INFO + "(" + COLUMN_NAME         + " TEXT NOT NULL PRIMARY KEY," + COLUMN_URL + " TEXT NOT NULL,"         + COLUMN_DOWNLOADED + " TEXT NOT NULL)"; 

ImportVocabList is an Asynctask. This is the onPostExecute :

**      * Method called after execution has happen, passing in the result      *       * @Override      */     protected void onPostExecute(ArrayList<Word> result) {         super.onPostExecute(result);         progressDialog.dismiss();         boolean b = false;         open();         for (Word w : result) {              addWord(w, vlName);         }         if (getAllVocabListsWhere(DatabaseManipulator.COLUMN_DOWNLOADED,                 "false").size() == 0) {             b = true;         }         close();         if (b) {             context.finish();         }     } 

The method addWord is as follows :

          public boolean addWord(Word w, String name) {     try {         ContentValues cv = new ContentValues();         cv.put(COLUMN_NAME, name);         cv.put(COLUMN_WORD_FOREIGN, w.getWordForeign());         cv.put(COLUMN_WORD_ENGLISH, w.getWordEnglish());         cv.put(COLUMN_CORRECT, w.getCorrect());         database.insert(TABLE_VOCAB_WORDS, null, cv);         return true;     } catch (SQLiteException e) {         System.out.println("SQL ERROR");         return false;     } } 

The problem has been fixed - there were duplicate entries but they were ignored. Thanks

回答1:

Looking at your AsyncTask's onPostExecute() method, I am confident that your have at least one duplicate set of values in result. Simply purge these duplicates from your source.

Or you can tell your table to ignore the rows with duplicate entries and carry on via a "conflict-clause":

private static final String CREATE_DB_TB_2 = "CREATE TABLE "         + TABLE_VOCAB_WORDS + "(" + COLUMN_NAME + " TEXT NOT NULL,"         + COLUMN_WORD_FOREIGN + " TEXT NOT NULL," + COLUMN_WORD_ENGLISH         + " TEXT NOT NULL," + COLUMN_CORRECT         + " BYTE NOT NULL, PRIMARY KEY (" + COLUMN_NAME + ","         + COLUMN_WORD_FOREIGN + ") ON CONFLICT IGNORE)"; 


回答2:

name and foreign_word make up your primary (Unique!) key in this table. you must be trying to insert duplicated keyed rows. The combination of the two fields must be unique.



回答3:

Use

db.insertOrThrow(TABLE_VOCAB_WORDS, null, cv); 

It worked for me for reasons I ignore.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!