SQLite PRIMARY key AutoIncrement doesn't work

故事扮演 提交于 2019-12-10 18:48:34

问题


I'm trying to a have a table with an auto incremented primary key. The SQL query for table creation is included.
Problem is the auto-increment does not work. Meaning when I insert a row with NULL as the value of conversation_id it just inserts null. I have this problem on multiple tables.

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

The following is the method I use to insert into 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;
    }

The curious thing here is when I retrieve the insert id from insert method it returns the correct value, but the actual database field is null.

If I understand correctly A column declared INTEGER PRIMARY KEY will autoincrement. [Cite]


回答1:


From documentation:

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.

You don't have to add UNIQUE constraint on a COLUMN that has PRIMARY KEY constraint.
Explanation:

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

Instead add NOT NULL. This is why:

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.


I recommend using this Column definition:

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



回答2:


I just put autoincrement in the query and it works fine .

like this

id  integer primary key autoincrement



回答3:


Most likely the return value you are seeing is the row's ROWID. A ROWID is a hidden column available in every table, unless explicitly removed. According to the official documentation, when you define an INTEGER PRIMARY KEY, it should automatically become an alias for the ROWID. That's also why AUTOINCREMENT is not needed when you define your column in this way.

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.

See: CREATE TABLE documentation

Either your column is not an INTEGER, or it is not a PRIMARY KEY. Taking a closer look at your create-statement I can see one or two possible culprits.

UNIQUE vs. PRIMARY KEY

A primary key is unique by default. According to the syntax definition (which you can find on the same documentation page as the citation above) you should choose either PRIMARY KEY or UNIQUE, not both.

COLUMN length restrictions

ROWID is already 64-bit by default. You have specified length 64, but lengths are not specified in bits. You may have specified a 64-byte integer here, which I'm sure was not intended. This should actually not be a problem however, since SQLite ignores length-constraints. So it is not meaningful to specify them.

TLDR

Replace this code:

conversation_id INTEGER (64) PRIMARY KEY UNIQUE

With this:

conversation_id INTEGER PRIMARY KEY AUTOINCREMENT


来源:https://stackoverflow.com/questions/30422782/sqlite-primary-key-autoincrement-doesnt-work

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