SQLite PRIMARY 键自动增量不起作用
Posted
技术标签:
【中文标题】SQLite PRIMARY 键自动增量不起作用【英文标题】:SQLite PRIMARY key AutoIncrement doesn't work 【发布时间】:2015-08-06 00:23:16 【问题描述】:我正在尝试创建一个带有自动递增主键的表。包括用于创建表的 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]
【问题讨论】:
以下划线开头,例如:_id。 @Krupal 没有成功我的朋友。 【参考方案1】:我只是在查询中添加了自动增量,它工作正常。
喜欢这个
id integer primary key autoincrement
【讨论】:
【参考方案2】:来自文档:
使用 CREATE TABLE AS 创建的表没有 PRIMARY KEY 并且没有 任何形式的约束。每列的默认值为NULL。
您不必在具有 PRIMARY KEY
约束的 COLUMN 上添加 UNIQUE
约束。
说明:
UNIQUE 约束类似于 PRIMARY KEY 约束,除了 单个表可能有任意数量的 UNIQUE 约束。
改为添加NOT NULL
。
这就是为什么:
根据 SQL 标准,PRIMARY KEY 应该总是暗示 NOT 空值。不幸的是,由于一些早期版本中的错误,这不是 SQLite 中的案例。除非该列是 INTEGER PRIMARY KEY 或 表是 WITHOUT ROWID 表或列被声明为 NOT NULL, SQLite 允许在 PRIMARY KEY 列中使用 NULL 值。 SQLite 可能是 固定以符合标准,但这样做可能会破坏传统 应用程序。因此,决定仅记录事实 该 SQLite 允许在大多数 PRIMARY KEY 列中使用 NULL。
我建议使用此列定义:
CREATE TABLE conversations (
conversation_id INTEGER PRIMARY KEY NOT NULL AUTOINCREMENT,
...
【讨论】:
我已经测试了NOT NULL
,但由于这个约束,它无法完全插入一行。
终于!似乎应该明确声明AUTOINCEREMENT
。【参考方案3】:
您看到的返回值很可能是该行的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
。仔细查看您的创建语句,我可以看到一两个可能的罪魁祸首。
唯一与主键
默认情况下,主键是唯一的。根据语法定义(您可以在与上述引用相同的文档页面上找到),您应该选择PRIMARY KEY
或UNIQUE
,而不是两者。
列长度限制
ROWID
默认已经是 64 位了。您已指定长度 64,但未以位为单位指定长度。您可能在这里指定了一个 64 字节的整数,我确定这不是故意的。然而,这实际上应该不是问题,因为SQLite ignores length-constraints。所以指定它们没有意义。
TLDR
替换此代码:
conversation_id INTEGER (64) PRIMARY KEY UNIQUE
有了这个:
conversation_id INTEGER PRIMARY KEY AUTOINCREMENT
【讨论】:
以上是关于SQLite PRIMARY 键自动增量不起作用的主要内容,如果未能解决你的问题,请参考以下文章
CentOS 6 - YUM 不起作用 - primary.sqlite.bz2 [错误 -1] 元数据文件与校验和不匹配
用整数替换 sqlite.net “bigint” 以实现自动增量主键约束