【问题标题】:Find duplicate entries in SQLite database with Android使用 Android 在 SQLite 数据库中查找重复条目
【发布时间】:2012-09-18 03:56:40
【问题描述】:

我在 Android 中使用 SQLite 数据库,用户必须输入名称、ip 和 url,然后将其保存在数据库中。我希望能够识别名称列中是否有双重条目,但我不知道如何对其进行编程。我认为创建专栏UNIQUE 是正确的方式...

我的 SQLAdapter:

public class ProjectsDBAdapter {

 public static final String KEY_ROWID = "_id";
 public static final String KEY_PROJECTNAME = "projectname";
 public static final String KEY_ROUTERIP = "routerip";
 public static final String KEY_URL = "url";
 public static final String KEY_CALIMERO = "calimero";

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

 private static final String DATABASE_NAME = "KNXTable";
 private static final String SQLITE_TABLE = "Project";
 private static final int DATABASE_VERSION = 1;

 private final Context mCtx;

 private static final String DATABASE_CREATE =
  "CREATE TABLE if not exists " + SQLITE_TABLE + " (" +
  KEY_ROWID + " integer PRIMARY KEY autoincrement," +
  KEY_ROUTERIP + "," +
  KEY_PROJECTNAME + "," +
  KEY_URL + "," +
  KEY_CALIMERO + "," +
  "UNIQUE("+KEY_PROJECTNAME+")"+");";

 private static class DatabaseHelper extends SQLiteOpenHelper {

  DatabaseHelper(Context context) {
   super(context, DATABASE_NAME, null, DATABASE_VERSION);
  }

  @Override
  public void onCreate(SQLiteDatabase db) {
   //invoked when the database is created, 
   //this is where we can create tables and columns to them, create views or triggers.
   Log.w(TAG, DATABASE_CREATE);
   db.execSQL(DATABASE_CREATE);
  }

  public long createProject(String ip, String name, 
   String url, String calimero) {

  ContentValues initialValues = new ContentValues();
  initialValues.put(KEY_ROUTERIP, ip);
  initialValues.put(KEY_PROJECTNAME, name);
  initialValues.put(KEY_URL, url);
  initialValues.put(KEY_CALIMERO, calimero);

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

希望您能给我一些提示,我已经尝试在创建表时使用 UNIQUE 但没有成功...

更新

SQLiteAdapter 中的方法:

 public long createProject(String ip, String name, 
   String url, String calimero) {

  ContentValues initialValues = new ContentValues();
  initialValues.put(KEY_ROUTERIP, ip);
  initialValues.put(KEY_PROJECTNAME, name);
  initialValues.put(KEY_URL, url);
  initialValues.put(KEY_CALIMERO, calimero);

  return mDb.insertOrThrow(SQLITE_TABLE, null, initialValues);
 }

我活动中的调用:

 //DATABASE
 // Add project to Database
 dbHelper = new ProjectsDBAdapter(this);
 dbHelper.open();

 //Add Strings to database
 dbHelper.insertSomeProjects(IP, Name, URL, Calimero);
 //Generate ListView from SQLite Database
 displayListView();

和 logcat 输出:

01-27 00:02:56.555: E/AndroidRuntime(28526): FATAL EXCEPTION: main
01-27 00:02:56.555: E/AndroidRuntime(28526): java.lang.RuntimeException: Unable to start activity ComponentInfo{de.bertrandt.bertrandtknx/de.bertrandt.bertrandtknx.ProjectList}: android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
01-27 00:02:56.555: E/AndroidRuntime(28526):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1970)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1995)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at android.app.ActivityThread.access$600(ActivityThread.java:128)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1161)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at android.os.Looper.loop(Looper.java:137)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at android.app.ActivityThread.main(ActivityThread.java:4514)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at java.lang.reflect.Method.invokeNative(Native Method)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at java.lang.reflect.Method.invoke(Method.java:511)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at dalvik.system.NativeStart.main(Native Method)
01-27 00:02:56.555: E/AndroidRuntime(28526): Caused by: android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
01-27 00:02:56.555: E/AndroidRuntime(28526):    at android.database.sqlite.SQLiteStatement.native_executeInsert(Native Method)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:113)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1839)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at android.database.sqlite.SQLiteDatabase.insertOrThrow(SQLiteDatabase.java:1738)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at SQLite.ProjectsDBAdapter.createProject(ProjectsDBAdapter.java:89)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at SQLite.ProjectsDBAdapter.insertSomeProjects(ProjectsDBAdapter.java:140)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at de.bertrandt.bertrandtknx.ProjectList.setup(ProjectList.java:120)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at de.bertrandt.bertrandtknx.ProjectList.onCreate(ProjectList.java:55)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at android.app.Activity.performCreate(Activity.java:4562)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1053)
01-27 00:02:56.555: E/AndroidRuntime(28526):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1934)
01-27 00:02:56.555: E/AndroidRuntime(28526):    ... 11 more

解决方案

//Add Strings to database
try {
     dbHelper.insertSomeProjects(IP, Name, URL, Calimero);
} catch (SQLiteException exception) {
     Log.d("SQLite", "Error"+exception.toString());
     Toast.makeText(getApplicationContext(),
        "Name is duplicated", Toast.LENGTH_SHORT).show();
            exception.printStackTrace();
}

【问题讨论】:

    标签: android database sqlite duplicates


    【解决方案1】:

    将 UNIQUE 声明放在列定义部分,如此相关问题所示:

    SQLite table constraint - unique on multiple columns

    您的示例在 UNIQUE 子句中只有一个列,并且您可能希望在发生冲突时使用不同的策略(例如,可能拒绝插入而不是替换)

    CREATE TABLE a (i INT, j INT, UNIQUE(i) ON CONFLICT REPLACE);
    

    【讨论】:

    • 我现在尝试了this 方式,看起来几乎相同,但仍然无法正常工作......
    • 这样表就创建好了,但是你可以插入重复的项目名称而不会在插入时抛出错误?你在寻找什么行为?您想防止重复插入并引发异常,还是在尝试重复插入时应用策略(REPLACE 等)?
    • 是的,我的创建表看起来像这个私有静态最终字符串DATABASE_CREATE = "CREATE TABLE if not exists " + SQLITE_TABLE + " (" + KEY_ROWID + " integer PRIMARY KEY autoincrement," + KEY_ROUTERIP + "," + KEY_PROJECTNAME + "," + KEY_URL + "," + KEY_CALIMERO + "," + "UNIQUE("+KEY_PROJECTNAME+")"+");";,但是如果 routerip 重复则会引发错误???
    • 我想创建一个 Toast 或 Dialog 提示该名称已保存在数据库中。我可以在抛出异常的情况下执行此操作吗?
    • 刚刚关闭您发布的代码,我不明白为什么 ROUTERIP 列会抛出错误。也许发布有问题的插入代码和 logcat?
    【解决方案2】:

    您可以将列创建为主键。例如:

    "CREATE TABLE mytable ("
    "field1 text,"
    "field2 text,"
    "field3 integer,"
    "PRIMARY KEY (field1)"
    ");"
    

    现在,当您尝试在此列 (field1) 中插入重复值时,您的代码会抛出 SQLException。您需要抓住SQLException 并采取适当的行动。

    如果您没有太多要处理的行,您应该考虑填充一个包含所有名称的ArrayList,并使用myArrayList.contains(myNameVariable) 来检查一个名称是否已经被之前处理过。然后,您将能够避免实际执行 SQL 语句来查看它是否抛出异常。

    【讨论】:

    • 这也有效,但我仍然遇到与煎饼帖子中描述的相同的问题
    • 您显然可以在 catch 块中向用户显示 Toast 消息。您所需要的只是应用程序上下文
    • 好的,我会尝试,但目前我的 porgram 在wearg 列中抛出异常,我不知道为什么......我已经编辑了我的主要帖子,也许你可以找到问题跨度>
    • 你需要把 mDb.insertOrThrow(SQLITE_TABLE, null, initialValues);在 try catch 块中。从您的日志中可以明显看出约束失败。捕获异常并检查它是否是由于约束失败,然后显示你的 toast!
    • 好的,现在可以了,我已将代码添加到我的主帖中。谢谢!
    猜你喜欢
    • 2016-07-23
    • 1970-01-01
    • 2010-09-30
    • 1970-01-01
    • 2012-04-11
    • 2015-06-02
    • 2012-12-04
    • 2014-07-17
    • 2012-10-15
    相关资源
    最近更新 更多