SQLite 主键自动增量不起作用

SQLite PRIMARY key AutoIncrement doesn't work

我正在尝试 table 具有自动递增的主键。包含 SQL 创建 table 的查询。
问题是自动增量不起作用。意思是当我插入一行 NULL 作为 conversation_id 的值时,它只是插入 null。我在多个 table 上遇到这个问题。

-- 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) 
);

下面是我用来插入table的方法:

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 时,它 returns 是正确的值,但实际的数据库字段为空。

如果我没理解错的话A column declared INTEGER PRIMARY KEY will autoincrement.[Cite]

我只是在查询中添加了自动增量,它工作正常。

像这样

id  integer primary key autoincrement

来自文档:

A table created using CREATE TABLE AS has no PRIMARY KEY and no constraints of any kind. The default value of each column is NULL.

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

A UNIQUE constraint is similar to a PRIMARY KEY constraint, except that a single table may have any number of UNIQUE constraints.

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

According to the SQL standard, PRIMARY KEY should always imply NOT NULL. Unfortunately, due to a bug in some early versions, this is not the case in SQLite. Unless the column is an INTEGER PRIMARY KEY or the table is a WITHOUT ROWID table or the column is declared NOT NULL, SQLite allows NULL values in a PRIMARY KEY column. SQLite could be fixed to conform to the standard, but doing so might break legacy applications. Hence, it has been decided to merely document the fact that SQLite allowing NULLs in most PRIMARY KEY columns.


我建议使用此列定义:

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

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

With one exception noted below, if a rowid table has a primary key that consists of a single column and the declared type of that column is "INTEGER" in any mixture of upper and lower case, then the column becomes an alias for the rowid. Such a column is usually referred to as an "integer primary key". A PRIMARY KEY column only becomes an integer primary key if the declared type name is exactly "INTEGER". Other integer type names like "INT" or "BIGINT" or "SHORT INTEGER" or "UNSIGNED INTEGER" causes the primary key column to behave as an ordinary table column with integer affinity and a unique index, not as an alias for the rowid.

参见:CREATE TABLE documentation

您的专栏不是 INTEGER,或者不是 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