奇怪 org.sqlite.SQLiteException: [SQLITE_ERROR] SQL 错误或缺少数据库(外键不匹配 -
Strange org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (foreign key mismatch -
我 运行 into org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (foreign key mismatch - ...
发表声明,使用正常的 SQLite-frontend 没有任何投诉。这创建了我的数据库的关键部分:
CREATE TABLE IF NOT EXISTS artists (
aid INTEGER PRIMARY KEY AUTOINCREMENT,
aname VARCHAR(200) NOT NULL,
CONSTRAINT one UNIQUE(aname)
);
CREATE TABLE IF NOT EXISTS discs (
did INTEGER PRIMARY KEY AUTOINCREMENT,
testAddCD1 BIGINT(10) NOT NULL,
dtitle VARCHAR(125) NOT NULL,
dreleaseyear YEAR(4) DEFAULT NULL,
dlang VARCHAR(3) DEFAULT NULL
);
CREATE TABLE IF NOT EXISTS tracks (
discs_did INTEGER NOT NULL,
tnumber INT(4) NOT NULL,
ttitle VARCHAR(125) NOT NULL,
tseconds INT(4) NOT NULL,
CONSTRAINT pk PRIMARY KEY(discs_did, tnumber),
CONSTRAINT fk FOREIGN KEY(discs_did) REFERENCES discs(did) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT val CHECK(tseconds> 0)
);
CREATE TABLE IF NOT EXISTS track_by_artist (
discs_did INTEGER NOT NULL,
tracks_tnumber INT(4) NOT NULL,
artists_aid INTEGER NOT NULL,
CONSTRAINT pk PRIMARY KEY(discs_did, tracks_tnumber, artists_aid),
CONSTRAINT fk1 FOREIGN KEY(discs_did) REFERENCES discs(did) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT fk2 FOREIGN KEY(tracks_tnumber) REFERENCES tracks(tnumber) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT fk3 FOREIGN KEY(artists_aid) REFERENCES artists(aid) ON DELETE RESTRICT ON UPDATE RESTRICT
数据库已创建,JDBC-驱动程序插入艺术家、光盘和光盘曲目 - 一切正常。最后的插入应该将艺术家分配给曲目,看起来像
INSERT INTO track_by_artist (discs_did, tracks_tnumber, artists_aid) VALUES (1, 1, 1);
使用 JDBC 这会产生
SQLite-Error #1
org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (foreign key mismatch - "track_by_artist" referencing "tracks")
at org.sqlite.core.DB.newSQLException(DB.java:1012)
at org.sqlite.core.DB.newSQLException(DB.java:1024)
at org.sqlite.core.DB.throwex(DB.java:989)
at org.sqlite.core.NativeDB.prepare_utf8(Native Method)
at org.sqlite.core.NativeDB.prepare(NativeDB.java:134)
at org.sqlite.core.DB.prepare(DB.java:257)
at org.sqlite.core.CorePreparedStatement.<init>(CorePreparedStatement.java:45)
at org.sqlite.jdbc3.JDBC3PreparedStatement.<init>(JDBC3PreparedStatement.java:30)
at org.sqlite.jdbc4.JDBC4PreparedStatement.<init>(JDBC4PreparedStatement.java:25)
at org.sqlite.jdbc4.JDBC4Connection.prepareStatement(JDBC4Connection.java:35)
at org.sqlite.jdbc3.JDBC3Connection.prepareStatement(JDBC3Connection.java:241)
at org.sqlite.jdbc3.JDBC3Connection.prepareStatement(JDBC3Connection.java:205)
发布相同的 SQL-Insert with SQLite 的文本前端就像奶油一样。
我有点迷茫,不知道如何处理我的 Java-代码。
有什么建议吗?
克里斯
问题是您在 track_by_artist
中定义了这个外键约束:
CONSTRAINT fk2 FOREIGN KEY(tracks_tnumber) REFERENCES tracks(tnumber) ON DELETE RESTRICT ON UPDATE RESTRICT
尽管 tracks
中的 tnumber
不是 UNIQUE
(也不应该是)。
外键的父项必须定义为 UNIQUE
.
在tracks
中,PRIMARY KEY
被定义为discs_did
和tnumber
的组合,这是有道理的,所以这两列的组合是唯一的。
您可以在 track_by_artist
中为列 discs_did
和 tracks_tnumber
定义一个复合外键,引用 discs_did
和 tnumber
tracks
:
CREATE TABLE IF NOT EXISTS track_by_artist (
discs_did INTEGER NOT NULL,
tracks_tnumber INT(4) NOT NULL,
artists_aid INTEGER NOT NULL,
CONSTRAINT pk PRIMARY KEY(discs_did, tracks_tnumber, artists_aid),
CONSTRAINT fk1 FOREIGN KEY(discs_did, tracks_tnumber) REFERENCES tracks(discs_did, tnumber) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT fk2 FOREIGN KEY(artists_aid) REFERENCES artists(aid) ON DELETE RESTRICT ON UPDATE RESTRICT
);
这样您就不需要为 discs_did
.
单独定义外键
我 运行 into org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (foreign key mismatch - ...
发表声明,使用正常的 SQLite-frontend 没有任何投诉。这创建了我的数据库的关键部分:
CREATE TABLE IF NOT EXISTS artists (
aid INTEGER PRIMARY KEY AUTOINCREMENT,
aname VARCHAR(200) NOT NULL,
CONSTRAINT one UNIQUE(aname)
);
CREATE TABLE IF NOT EXISTS discs (
did INTEGER PRIMARY KEY AUTOINCREMENT,
testAddCD1 BIGINT(10) NOT NULL,
dtitle VARCHAR(125) NOT NULL,
dreleaseyear YEAR(4) DEFAULT NULL,
dlang VARCHAR(3) DEFAULT NULL
);
CREATE TABLE IF NOT EXISTS tracks (
discs_did INTEGER NOT NULL,
tnumber INT(4) NOT NULL,
ttitle VARCHAR(125) NOT NULL,
tseconds INT(4) NOT NULL,
CONSTRAINT pk PRIMARY KEY(discs_did, tnumber),
CONSTRAINT fk FOREIGN KEY(discs_did) REFERENCES discs(did) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT val CHECK(tseconds> 0)
);
CREATE TABLE IF NOT EXISTS track_by_artist (
discs_did INTEGER NOT NULL,
tracks_tnumber INT(4) NOT NULL,
artists_aid INTEGER NOT NULL,
CONSTRAINT pk PRIMARY KEY(discs_did, tracks_tnumber, artists_aid),
CONSTRAINT fk1 FOREIGN KEY(discs_did) REFERENCES discs(did) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT fk2 FOREIGN KEY(tracks_tnumber) REFERENCES tracks(tnumber) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT fk3 FOREIGN KEY(artists_aid) REFERENCES artists(aid) ON DELETE RESTRICT ON UPDATE RESTRICT
数据库已创建,JDBC-驱动程序插入艺术家、光盘和光盘曲目 - 一切正常。最后的插入应该将艺术家分配给曲目,看起来像
INSERT INTO track_by_artist (discs_did, tracks_tnumber, artists_aid) VALUES (1, 1, 1);
使用 JDBC 这会产生
SQLite-Error #1
org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (foreign key mismatch - "track_by_artist" referencing "tracks")
at org.sqlite.core.DB.newSQLException(DB.java:1012)
at org.sqlite.core.DB.newSQLException(DB.java:1024)
at org.sqlite.core.DB.throwex(DB.java:989)
at org.sqlite.core.NativeDB.prepare_utf8(Native Method)
at org.sqlite.core.NativeDB.prepare(NativeDB.java:134)
at org.sqlite.core.DB.prepare(DB.java:257)
at org.sqlite.core.CorePreparedStatement.<init>(CorePreparedStatement.java:45)
at org.sqlite.jdbc3.JDBC3PreparedStatement.<init>(JDBC3PreparedStatement.java:30)
at org.sqlite.jdbc4.JDBC4PreparedStatement.<init>(JDBC4PreparedStatement.java:25)
at org.sqlite.jdbc4.JDBC4Connection.prepareStatement(JDBC4Connection.java:35)
at org.sqlite.jdbc3.JDBC3Connection.prepareStatement(JDBC3Connection.java:241)
at org.sqlite.jdbc3.JDBC3Connection.prepareStatement(JDBC3Connection.java:205)
发布相同的 SQL-Insert with SQLite 的文本前端就像奶油一样。
我有点迷茫,不知道如何处理我的 Java-代码。
有什么建议吗?
克里斯
问题是您在 track_by_artist
中定义了这个外键约束:
CONSTRAINT fk2 FOREIGN KEY(tracks_tnumber) REFERENCES tracks(tnumber) ON DELETE RESTRICT ON UPDATE RESTRICT
尽管 tracks
中的 tnumber
不是 UNIQUE
(也不应该是)。
外键的父项必须定义为 UNIQUE
.
在tracks
中,PRIMARY KEY
被定义为discs_did
和tnumber
的组合,这是有道理的,所以这两列的组合是唯一的。
您可以在 track_by_artist
中为列 discs_did
和 tracks_tnumber
定义一个复合外键,引用 discs_did
和 tnumber
tracks
:
CREATE TABLE IF NOT EXISTS track_by_artist (
discs_did INTEGER NOT NULL,
tracks_tnumber INT(4) NOT NULL,
artists_aid INTEGER NOT NULL,
CONSTRAINT pk PRIMARY KEY(discs_did, tracks_tnumber, artists_aid),
CONSTRAINT fk1 FOREIGN KEY(discs_did, tracks_tnumber) REFERENCES tracks(discs_did, tnumber) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT fk2 FOREIGN KEY(artists_aid) REFERENCES artists(aid) ON DELETE RESTRICT ON UPDATE RESTRICT
);
这样您就不需要为 discs_did
.