创建唯一索引无助于停止重复

时间:2014-10-02 08:51:09

标签: java android sql sqlite unique-index

我有一个名为details的主数据库表,其中包含三个感兴趣的列 -

_id | Name | BirthDate | xx | xx | xx | ...

我使用以下语句在上表中创建一个唯一索引:

CREATE UNIQUE INDEX _id ON Details (Name, BirthDate)

以上的目的是阻止表中的重复条目,我不希望任何名称和生日相同。 (虽然我不确定是否这样做,但我尝试插入一个具有相同生日和名称的新记录,我发现以前现有的记录具有相同的凭据被删除,而这个新记录在最后插入) - 但这是在我介绍以下内容之前并非如此:

我有一个单独的表,如下所示,名为Notifications:

| _id | NotificationFor | DateToNotify | IsExtraordinary | NotificationData | NotificationDateFor | TypeNotification | RadioType | FriendsName | PrimaryId |

以上两个表已映射:详细信息表中的_id是通知表中的PrimaryId

对于Details表中的每个_id(记录),将记录四个记录,并将所有记录插入Notifications表中。

现在问题是我不想在任何表中重复记录,所以我在Notifications表上放了一个Unique索引,如下所示:

CREATE UNIQUE INDEX _id ON Notifications (NotificationFor, DateToNotify, IsExtraordinary,NotificationData,NotificationDateFor,TypeNotification,RadioType,FriendsName,PrimaryId);

我收到以下错误:

10-02 14:16:31.439: E/AndroidRuntime(31743): FATAL EXCEPTION: main
10-02 14:16:31.439: E/AndroidRuntime(31743): java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx.xxx.xxx}: android.database.sqlite.SQLiteException: index _id already exists (code 1): , while compiling: CREATE UNIQUE INDEX _id ON Notifications (NotificationFor, DateToNotify, IsExtraordinary,NotificationData,NotificationDateFor,TypeNotification,RadioType,FriendsName,PrimaryId );

在我的DBAdapter中,我按如下方式执行代码:

db.execSQL(uniqueDetails); 
db.execSQL(uniqueNotifications);

我将uniqueNotifications查询更改为:

CREATE UNIQUE INDEX NotificationDateFor ON Notifications (NotificationFor, DateToNotify, IsExtraordinary,NotificationData,NotificationDateFor,TypeNotification,RadioType,FriendsName,PrimaryId );

现在我没有收到错误,但我在通知表中看到了重复项。 ANy暗示我如何改进上述内容并使其有效?

为了增强上述内容,我从文件中读取记录并将它们插入到表中我首先计算我的数据并将其插入到详细信息中。在这种情况下,在for循环中我没有在通知上使用UNIQUE - 我的UNIQUE详细信息工作正常。但是如果我遇到了来自Details的重复,我想停止for循环的迭代并跳转到下一次迭代,因为我不希望在Notifications表中输入重复项 - 是否有UNIQUE Query的返回类型 - 如果执行在详细信息我发现一个副本我想将我的循环切换到下一个迭代 - 跳过关于通知表的插入语句。对不起我知道我不善于解释东西。

编辑:

我在表格的末尾添加了以下记录,而在插入之前,我有原始形式的记录 - 现在我没有看到旧的记录,但是最新的记录已插入到最后:

详细信息表 - 我无法重现两者,因为已删除了一个。

通知表中的对应部分:(记录名为Tom Hanks的顶部)

Record named Tom Hanks at the top

在同一张表的底部用不同的_id重复记录:

enter image description here

下面我重现了Details表,如果你观察到记录号90不再存在 - 因为它可能在插入'same-value'记录之前被删除:( _id和{{1} }值被映射)

enter image description here

编辑:

以下是我的插入声明(详见表格):

PrimaryId

我认为上面的INSERT OR REPLACE可能会产生问题。

1 个答案:

答案 0 :(得分:0)

使用唯一约束来强制使用唯一值。

private static final String VERSION_60_CREATE_TABLE = "CREATE TABLE "
        + TABLE_MARKERS + "(" + KEY_ID + " INTEGER PRIMARY KEY,"
        + KEY_MARKER_LOCATION_ID + " INTEGER," + KEY_MARKER_IMAGE_ID
        + " INTEGER DEFAULT -1," + KEY_MARKER_IMAGE_PATH + " TEXT,"
        + KEY_MARKER_SNIPPET + " TEXT," + KEY_MARKER_TITLE + " TEXT,"
        + " FOREIGN KEY(" + KEY_MARKER_LOCATION_ID + ") REFERENCES "
        + TABLE_LOCATIONS + "(" + KEY_ID + ")," + " CONSTRAINT UNQ_"
        + KEY_MARKER_IMAGE_ID + " UNIQUE (" + KEY_MARKER_IMAGE_ID
        + ") ON CONFLICT ABORT)";

最佳实践:在代码中为约束赋予含义全名。上面的示例使用UNQ_与约束名称的列名连接。使用db gui设计器,使用设计器中的约束名称。