我是SQL的新手,我希望 contracts_tb (下面的查询详情)是显示和链接引用的外来ID键:
med_idref (referred from med_id (INTEGER), PRIMARY KEY o mediaadv_tb),
mediatitle_ref (title (TEXT), mediaadv_tb),
mediatype_red (mtype (TEXT), mediaadv_tb),
cus_idref (cus_id (INTEGER),PRIMARY KEY of customer_tb),
cus_companyref (referred from company (TEXT), in customer_tb)
全部链接并显示到 contracts_tb 。当我从 mediaadv_tb 和 customer_tb 添加/替换值时,我遇到了这个问题:
foreignkey mismatch
另外,我是否必须制作或分配父表?
查询:
DROP TABLE IF EXISTS customer_tb;
CREATE TABLE IF NOT EXISTS customer_tb (
cus_id INTEGER PRIMARY KEY,
company TEXT,
firstname TEXT,
middlename TEXT,
lastname TEXT,
gender TEXT,
dob TEXT,
dateregistered TEXT,
contactno TEXT,
emailaddress TEXT,
description TEXT,
refpic INTEGER,
cuspic BLOB
);
DROP TABLE IF EXISTS mediaadv_tb;
CREATE TABLE IF NOT EXISTS mediaadv_tb (
med_id INTEGER PRIMARY KEY,
mtype TEXT,
duration TEXT,
title TEXT,
dateadded TEXT,
desription TEXT,
previewimg BLOB,
filepath TEXT
);
DROP TABLE IF EXISTS contracts_tb;
CREATE TABLE IF NOT EXISTS contracts_tb (
contract_id INTEGER PRIMARY KEY,
customer_idref INTEGER REFERENCES customer_tb (cus_id),
media_idref INTEGER REFERENCES mediaadv_tb (med_id),
media_typeref TEXT REFERENCES mediaadv_tb(mtype),
media_titleref TEXT REFERENCES mediaadv_tb (title),
status TEXT,
priority TEXT,
dateadded TEXT,
dateexpiration TEXT,
amountpaid REAL,
arearofcoverage TEXT
);
错误: -
contracts_tb
mediaadv_tb
答案 0 :(得分:2)
我认为您的问题是因为定义的外键引用 media_typeref 和 media_titleref 列无效,因为它们没有或属于UNIQUE索引(无索引)。 SQLite Foreign Key Support - 3. Required and Suggested Database Indexes
引用的 id 列,因为它们是INTEGER PRIMARY KEY,是隐式UNIQUE索引。
此外,甚至不需要两列(typeref和titleref),因为media_idref列将用于标识引用,因此将保存相应的值。将这些值复制到合同表中将违反规范化,甚至可能造成严重的麻烦(例如,如果值发生变化,您必须找到所有其他用途并更改它们)。
因此我建议使用以下方法创建 contracts_tb : -
DROP TABLE IF EXISTS contracts_tb;
CREATE TABLE IF NOT EXISTS contracts_tb (
contract_id INTEGER PRIMARY KEY,
customer_idref INTEGER REFERENCES customer_tb (cus_id),
media_idref INTEGER REFERENCES mediaadv_tb (med_id),
status TEXT,
priority TEXT,
dateadded TEXT,
dateexpiration TEXT,
amountpaid REAL,
arearofcoverage TEXT
);
我正在制作的是Java NetBeans SQLite数据库程序,其中包括 使用合同框架,那里有一个新的合同 将是一个组合框,限制用户只放置现有的 contract_tb中引用的id或名称随后提供 选择。先生可以吗?
是
更具体地说: -
假设您有客户 Fred,Bert和Harry(分别为ID 1,2和3)。并且你有 mediaadv 的M1,M2和M3(id为10,11和12(不是1,2和3来帮助区分mediaadv和客户))。
此外,我将假设建议的contract_tb表而不是问题中的原始表(即按建议删除2列)
在插入新合同时,您会提供客户的列表(组合框),例如
佛瑞德
伯特
哈利
(此列表可以通过以下查询生成: -
SELECT cus_id,firstname FROM customer_tb;
即所有现有客户
如果您想要Fred James Bloggs,那么您可以使用: -
SELECT cus_id,firstname||' '||middlename||'lastname' AS fullname FROM customer_tb;
。同样,可以从查询中生成现有mediaadv的列表,例如: -
SELECT med_id, description FROM mediaadv_tb;
例如所以组合框会有: -
M1
M2
M3
现在,如果合同是针对Bert(id 2 )和M1(id 10 ),那么您构建的SQL类似于: -
INSERT INTO contracts_tb VALUES(null,2,10,'the_status','the_priority','yyyy-mm-dd','yyyy-mm-dd',500,'the_coverage');
其他值是他们应该的。
注意上面INSERT的使用要求给出所有列。您可以通过指定列的列表来跳过列,例如INSERT INTO contracts_tb (customer_idref,media_idref) VALUES(2,10);
当cus_id为2(Bert)的客户存在时,customer_idref是customer_tb中现有id的约束是好/符合且没有冲突。
同样,因为mediaadv_tb中有一行med_id为10,所以这个约束很好/符合并且没有冲突。
但是说SQL是: -
INSERT INTO contracts_tb VALUES(null,2,100,'the_status','the_priority','yyyy-mm-dd','yyyy-mm-dd',500,'the_coverage');
然后因为没有med_id为100的约束,说media_idref必须在mediaadv_tb,列med_id中引用值100(在本例中),那么将不会满足约束并且插入将失败。
再次,是的,我相信你想要的是可行的。
注意外键只是一个约束,它不会绑定/关联列或连接表。