【问题标题】:Why does referencing a SQLite rowid cause foreign key mismatch?为什么引用 SQLite rowid 会导致外键不匹配?
【发布时间】:2013-06-04 19:58:08
【问题描述】:
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

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

  • foo 存在。
  • foo.rowid 存在。
  • foo.rowidfoo 的主键,因此被限制为唯一性。
  • bar.foo_rowid 是一列,这与 foo.rowid 是一列的事实相符。

【问题讨论】:

    标签: sql database sqlite foreign-keys relational-database


    【解决方案1】:

    如果没有在表中定义,则不能使用rowid,但如果定义如下:

    CREATE TABLE IF NOT EXISTS Clase(
    ROWID INTEGER NOT NULL,
    nombre  VARCHAR(50) NOT NULL,
    PRIMARY KEY(ROWID));
    

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

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

    【讨论】:

      【解决方案2】:

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

      The parent key must be a named column or columns in the parent table, not the rowid.
      

      (见here。)

      您不能为此使用rowid,因此只需为表定义您自己的自动递增主键。

      【讨论】:

      • 甚至可以将PK命名为rowid
      • 我有一个错误说:外键不匹配 - "child_table" 引用 "parent_table" 。我按照你说的做了,但还是不行..
      • 另一方面,If a table contains a column of type INTEGER PRIMARY KEY, then that column becomes an alias for the ROWID. 来自 sqlite.org/autoinc.html
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      • 2012-01-05
      • 1970-01-01
      • 2021-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多