SQLite PRIMARY键AutoIncrement不起作用

时间:2015-05-24 11:03:43

标签: android sqlite android-sqlite auto-increment

我试图拥有一个带有自动递增主键的表。包括表创建的SQL查询 问题是自动增量不起作用。当我插入一个NULL为conversation_id的值的行时,它只是插入null。我在多个表上遇到这个问题。

-- Table: conversations
CREATE TABLE conversations (
    conversation_id INTEGER (64) PRIMARY KEY
                                 UNIQUE,
    target_id       BIGINT (64),
    sender_id       BIGINT (64),
    status          STRING (16)  NOT NULL
                                 DEFAULT unseen,
    is_group        INTEGER (1)  NOT NULL
                                 DEFAULT (0),
    last_update     INTEGER (32) DEFAULT (0),
    target_name     STRING (64),
    target_photo    STRING (256),
    unread_count    INTEGER (10) DEFAULT (0),
    last_message    STRING (256) 
);

以下是我用于插入表格的方法:

public Conversation addConversation(Conversation conversation) {
        SQLiteDatabase db = getWritableDatabase();
        ContentValues row = new ContentValues();

        row.put("target_id", conversation.getTargetID());
        row.put("sender_id", conversation.getSenderID());
        row.put("target_name", conversation.getTargetName());
        row.put("target_photo", conversation.getTargetPhoto());
        row.put("status", conversation.getStatus());
        row.put("unread_count", conversation.getUnreadCount());
        row.put("last_message", conversation.getLastMessage());

        conversation.setConversationID(db.insert(TBL_CONVERSATIONS, null, row));
        Log.d(TAG, "conversation added: "+conversation.getConversationID());

        db.close();

        return conversation;
    }

这里奇怪的是,当我从insert方法检索插入ID时,它返回正确的值,但实际的数据库字段为空。

如果我理解正确A column declared INTEGER PRIMARY KEY will autoincrement. [Cite]

3 个答案:

答案 0 :(得分:3)

来自文档:

  

使用CREATE TABLE AS创建的表没有PRIMARY KEY,没有   任何形式的约束。每列的默认值为NULL。

您不必在具有UNIQUE约束的COLUMN上添加PRIMARY KEY约束。
说明:

  

UNIQUE约束类似于PRIMARY KEY约束,除了   单个表可能有任意数量的UNIQUE约束。

而是添加NOT NULL。 这就是为什么:

  

根据SQL标准,PRIMARY KEY应始终表示NOT   空值。不幸的是,由于某些早期版本中的错误,事实并非如此   在SQLite中的情况。除非该列是INTEGER PRIMARY KEY或   table是WITHOUT ROWID表,或者列声明为NOT NULL,   SQLite允许PRIMARY KEY列中的NULL值。 SQLite可以   固定以符合标准,但这样做可能会破坏遗产   应用。因此,已决定仅记录事实   SQLite允许在大多数PRIMARY KEY列中使用NULL。


我建议使用此列定义:

CREATE TABLE conversations (
    conversation_id INTEGER PRIMARY KEY NOT NULL AUTOINCREMENT,
...
}

答案 1 :(得分:2)

我只是在查询中添加自动增量,它运行正常。

像这样

id  integer primary key autoincrement

答案 2 :(得分:2)

您看到的返回值很可能是行的ROWID。除非明确删除,否则ROWID是每个表中可用的隐藏列。根据官方文档,当您定义INTEGER PRIMARY KEY时,它应自动成为ROWID的别名。这也是以这种方式定义列时不需要AUTOINCREMENT的原因。

  

如下所示,如果rowid表有主键,则会出现一个例外情况   它由单个列和该列的声明类型组成   在大写和小写的任何混合物中都是“INTEGER”,然后是列   成为rowid的别名。通常提到这样的列   作为“整数主键”。 PRIMARY KEY列只会成为一个   如果声明的类型名称恰好是“INTEGER”,则为整数主键。   其他整数类型名称,如“INT”或“BIGINT”或“SHORT INTEGER”或   “UNSIGNED INTEGER”导致主键列表现为   普通表列具有整数亲和力和唯一索引,而不是   rowid的别名。

请参阅:CREATE TABLE documentation

您的列不是INTEGER,或者不是PRIMARY KEY。仔细看看你的创建语句我可以看到一两个可能的罪魁祸首。

UNIQUE与PRIMARY KEY

默认情况下,主键是唯一的。根据语法定义(您可以在与上面的引文相同的文档页面上找到),您应该选择PRIMARY KEYUNIQUE,而不是两者。

COLUMN长度限制

默认情况下,

ROWID已经是64位。您指定了长度64,但未以位为单位指定长度。你可能在这里指定了一个64字节的整数,我肯定不是这个整数。然而,这应该不是问题,因为SQLite ignores length-constraints。因此指定它们没有意义。

<强> TLDR

替换此代码:

conversation_id INTEGER (64) PRIMARY KEY UNIQUE

有了这个:

conversation_id INTEGER PRIMARY KEY AUTOINCREMENT