为什么引用SQLite rowid会导致外键不匹配?

Jor*_*dan 11 sql database sqlite foreign-keys relational-database

SQLite version 3.7.9 2011-11-01 00:52:41
sqlite> PRAGMA foreign_keys = 1;
sqlite> CREATE TABLE foo(name);
sqlite> CREATE TABLE bar(foo_rowid REFERENCES foo(rowid));
sqlite> INSERT INTO foo VALUES('baz');
sqlite> SELECT rowid, name FROM foo;
1|baz
sqlite> INSERT INTO bar (foo_rowid) VALUES (1);
Error: foreign key mismatch
Run Code Online (Sandbox Code Playgroud)

为什么会出现此错误?这是一个DML错误,但我不知道出了什么问题,因为:

  • foo 存在.
  • foo.rowid 存在.
  • foo.rowidfoo唯一性的主要关键因素.
  • bar.foo_rowid是一列,它匹配一列的事实foo.rowid.

Gor*_*off 17

SQLite文档在外键上非常清楚:

The parent key must be a named column or columns in the parent table, not the rowid.
Run Code Online (Sandbox Code Playgroud)

(见这里.)

您无法使用rowid此功能,因此只需为表定义自己的自动递增主键即可.

  • 另一方面,`如果一个表包含INTEGER PRIMARY KEY类型的列,那么该列将成为来自https://www.sqlite.org/autoinc.html的ROWID的别名. (3认同)
  • 甚至可以将PK命名为"rowid". (2认同)

小智 5

如果表中未定义,则不能使用 rowid,但如果按如下方式定义:

CREATE TABLE IF NOT EXISTS Clase(
ROWID INTEGER NOT NULL,
nombre  VARCHAR(50) NOT NULL,
PRIMARY KEY(ROWID));
Run Code Online (Sandbox Code Playgroud)

ROWID 列可以用来做外部引用,当你在表中插入一条记录时,ROWID 列的行为就像一个自增字段,这就是为什么推荐的 sqlite 没有自增字段的原因。

注意:ROWID 列可以被调用,否则只有它必须是 INTEGER 类型和表的主键。