【问题标题】:SQLite two rowid's created when I explicitly create one当我显式创建一个 SQLite 时创建了两个 rowid
【发布时间】:2013-08-26 21:34:05
【问题描述】:

我有一个 sqlite 表,当我 VACUUM 数据库时,我需要防止 id 发生变化。文档说 VACUUM 不会更改具有显式 INTEGER PRIMARY KEY 的表的 rowid。

所以,我用

创建了一个表
CREATE TABLE tableName (
  "rowid" INTEGER PRIMARY KEY, 
  "updated" DATETIME DEFAULT (CURRENT_TIMESTAMP),
  "description" TEXT
)

但这会产生一个包含两个 rowid 列的表。在 Firefox 的 SQLite Manager 插件中,我看到了两者,当我尝试访问 Java 中的结果集时,它显示“模糊列:'rowid'”。有没有办法显式创建 rowid 还是我必须使用不同的名称?

【问题讨论】:

    标签: java sqlite


    【解决方案1】:

    rowid is a column of every SQLite table by default

    如果表的主键由单个列组成,并且该列的声明类型为 INTEGER(大小写任意混合),则该列将成为 rowid 的别名。

    因此,您的 rowid 列不会替换默认的 rowid。您的键是默认 rowid 的 别名

    因此,您真的不应该将列命名为 rowid,因为它已经被使用过,并且会导致您已经经历过的“不明确的列”错误。

    文档说如果你的表包含一些 INTEGER PRIMARY KEY,SQLite 生成的 rowid 不会改变。 PK不需要是rowid。

    【讨论】:

    • 如果我这样做了,那么我必须返回并更改我的代码以使用 id 而不是 rowid。可行但...
    • 你确定吗?我记得在 SQLite 文档中读到,如果行定义包含 INTEGER PRIMARY KEY 的字段,则 SQLite 不会生成自己的内部 rowid。事实上,上面的链接就是包含该语言的文档。
    • 我可以建议将此部分添加到您的答案中吗? “如果一个表的主键由一个列组成,并且该列的声明类型为“INTEGER”,大小写任意混合,则该列成为rowid的别名。” 我发现这部分更能说明这个案例。
    • 实际上 Sqlite 总是创建列rowid,这就是重点。例如,如果您创建这样的列:myID INTEGER PRIMARY KEY,那么SELECT * FROM tablename WHERE myID = 1SELECT * from tablename WHERE tablename.rowid = 1 将都是有效的语句并且将检索相同的结果。自己试一试,以确保我已经这样做了,而且成功了。
    • 我现在明白你的意思了。公平地说,这种行为没有明确记录,但并非完全出乎意料。请参阅this 引用:您可以使用特殊列名 ROWID、_ROWID_ 或 OID 之一访问 SQLite 表的 ROWID。除非您声明一个普通表列使用这些特殊名称之一,否则该名称的使用将引用声明的列而不是内部 ROWID。 从这里我们可以推断实际上 sqlite 仍在创建自己的 @ 987654328@ 列,无论任何具有此名称的用户列。因此,我们将有两个 rowid 列。
    猜你喜欢
    • 2018-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-16
    • 2019-06-22
    • 1970-01-01
    • 2023-04-06
    相关资源
    最近更新 更多