问题
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