我正在将 SQLite3 用于简单的应用程序(如议程)。议程是多语言的。这就是为什么我的宴会厅使用更多语言(语言数必须是独立的)的原因
首先,我有一个表房间,其定义如下:
CREATE TABLE rooms
(
room_code VARCHAR2(32),
lang_code CHAR(2),
room_name VARCHAR(32),
PRIMARY KEY (room_code, lang_code),
FOREIGN KEY (lang_code) REFERENCES languages (lang_code),
CHECK (LENGTH(lang_code) = 2),
CHECK (room_code <> '')
);
然后我有一个表事件,定义如下:
CREATE TABLE events
(
room_code VARCHAR2(32) NOT NULL,
message_code VARCHAR(64) NOT NULL,
time_start DATETIME NOT NULL ,
time_end DATETIME NOT NULL,
PRIMARY KEY (message_code, room_code),
FOREIGN KEY (room_code) REFERENCES rooms (room_code),
-- Check the time is between 00:00 and 23:59
CHECK (time_start and time_end BETWEEN TIME('00:00') AND TIME('23:59')),
-- Start time must be lower than end time
CHECK (time_start < time_end),
-- Message code cannot be empty
CHECK (message_code <> '')
);
但是实际上,任何尝试插入的操作都会出现此错误:
Error: near line 91: foreign key mismatch - "events" referencing "rooms"
为什么我不能引用另一个表?我读到表B的所有外键都必须是表A中的PRIMARY KEY。但是这种依赖性对我来说还可以。表事件中的外键 room_code ,它也是表 rooms 中的主键 room_code 。
是否可以代替 TRIGGERS 解决此问题?实际上,如果可能的话,我想使用KEYS代替TRIGGERS。谢谢
最诚挚的问候
答案 0 :(得分:1)
我相信您的问题是由于不符合:-
通常,外键约束的父键是主键 父表的如果它们不是主键,则父键 键列必须共同受到UNIQUE约束,或者 有一个唯一索引。如果父键列具有UNIQUE索引, 那么该索引必须使用在中指定的排序规则序列 父表的CREATE TABLE语句。例如,
请注意主键,而不是部分主键。
简而言之,必须知道外键引用的列是唯一的。
因此,您可以为room_code列添加索引,也可以定义索引以利用UNIQUE约束,例如:-
DROP TABLE IF EXISTS events;
DROP TABLE IF EXISTS rooms;
DROP INDEX IF EXISTS room_code_idx;
CREATE TABLE IF NOT EXISTS rooms (
room_code VARCHAR2(32) UNIQUE, --<<<<<<<<<< ADDED UNIQUE
lang_code CHAR(2),
room_name VARCHAR(32),
PRIMARY KEY (room_code, lang_code),
-- FOREIGN KEY (lang_code) REFERENCES languages (lang_code)
CHECK (LENGTH(lang_code) = 2),
CHECK (room_code <> '')
);
CREATE TABLE IF NOT EXISTS events (
room_code VARCHAR2(32) NOT NULL,
message_code VARCHAR(64) NOT NULL,
time_start DATETIME NOT NULL ,
time_end DATETIME NOT NULL,
PRIMARY KEY (message_code, room_code),
FOREIGN KEY (room_code) REFERENCES rooms (room_code),
-- Check the time is between 00:00 and 23:59
CHECK (time_start and time_end BETWEEN TIME('00:00') AND TIME('23:59')),
-- Start time must be lower than end time
CHECK (time_start < time_end),
-- Message code cannot be empty
CHECK (message_code <> '')
);
INSERT INTO rooms VALUES('room001','xx','This is room 1');
INSERT INTO events VALUES('room001','This is a message for room 1','01:00','02:00');
结果:-
INSERT INTO rooms VALUES('room001','xx','This is room 1')
> Affected rows: 1
> Time: 0.3s
INSERT INTO events VALUES('room001','This is a message for room 1','01:00','02:00')
> Affected rows: 1
> Time: 0.301s
当然,您可以将PRIMARY KEY定义为 room_code 列,因为它必须是唯一的。
如果 room_code 列将/可能不是唯一的,并且唯一保证的唯一性将是 room_code 列和 lang_code 列的总和。您将需要定义一个复合外键(请参阅上面的链接)。