如何在插入时检查外键的值?

时间:2018-01-21 18:17:51

标签: sql sqlite

我正在使用Sqlite3自学SQL,非常适合我的永久游戏项目(难道我们都没有吗?)并且有以下表格:

CREATE TABLE equipment_types (
    row_id INTEGER PRIMARY KEY,
    type TEXT NOT NULL UNIQUE);

INSERT INTO equipment_types (type) VALUES ('gear'), ('weapon');

CREATE TABLE equipment_names (
    row_id INTEGER PRIMARY KEY,
    name TEXT NOT NULL UNIQUE);

INSERT INTO equipment_names (name) VALUES ('club'), ('band aids');

CREATE TABLE equipment (
    row_id INTEGER PRIMARY KEY,
    name INTEGER NOT NULL UNIQUE REFERENCES equipment_names,
    type INTEGER NOT NULL REFERENCES equipment_types);

INSERT INTO equipment (name, type) VALUES (1, 2), (2, 1);

现在我们有一个'club' 'weapon''band aids' 'gear'。我现在想制作一个weapons表;它将有equipment_id引用equipment表和武器属性,如伤害和范围等。我想将其约束为'weapon'类型的设备。

但对于我的生活,我无法理解。显然,CHECK只允许表达式,而不是子查询,我一直在努力创建一个可能完成这项工作的TRIGGER,但总之,我无法弄清楚查询和语法,或者如何检查结果,据我所知,它将以表格的形式,或null。

此外,有没有比W3School更先进的学习SQL的良好在线资源?请将它们添加为评论。

2 个答案:

答案 0 :(得分:1)

只需编写一个查询属于新记录的类型的查询:

CREATE TRIGGER only_weapons
BEFORE INSERT ON weapons
FOR EACH ROW
WHEN (SELECT et.type
      FROM euqipment_types AS et
      JOIN equipment AS e ON e.type = et.equipment_type_id
      WHERE e.row_id = NEW.equipment_id
     ) != 'weapon' 
BEGIN
    SELECT RAISE(FAIL, "not a weapon");
END;

答案 1 :(得分:-1)

外键引用应该是主键和同时。我会这样说:

CREATE TABLE equipment_types (
    equipment_type_id INTEGER PRIMARY KEY,
    type TEXT NOT NULL UNIQUE
);

INSERT INTO equipment_types (type) VALUES ('gear'), ('weapon');

CREATE TABLE equipment_names (
    equipment_name_id INTEGER PRIMARY KEY,
    name TEXT NOT NULL UNIQUE
);

INSERT INTO equipment_names (name) VALUES ('club'), ('band aids');


CREATE TABLE equipment (
    equipment_id INTEGER PRIMARY KEY,
    equipment_name_id INTEGER NOT NULL UNIQUE REFERENCES equipment_names(equipment_name_id),
    equipement_type_id INTEGER NOT NULL REFERENCES equipment_types(equipement_type_id)
);

我不会使用名称row_id作为主键。这是内置的默认设置,因此名称不是很好。在SQLite中,整数主键自动递增(参见here)。