我正在尝试为供应商组创建一个表,当我尝试创建它时会抛出错误。
以下是代码:
CREATE TABLE GROUPS_PLUS_SUPPLIERS
(
PRODUCT_GROUP_SUPPLIER_ID NUMBER(3),
GROUP_ID NUMBER(4),
GROUP_NAME VARCHAR2(255),
SUPPLIER_ID NUMBER(4),
CONSTRAINT PRODUCT_GROUP_SUPPLIER_ID_PK PRIMARY KEY (PRODUCT_GROUP_SUPPLIER_ID),
CONSTRAINT FK_SUPPLIER_ID FOREIGN KEY (SUPPLIER_ID) REFERENCES SUPPLIERS (SUPPLIER_ID)
);
CREATE TABLE PRODUCTS
(
PRODUCT_ID NUMBER (4),
PRODUCT_DESCRIPTION VARCHAR2 (255),
PRODUCT_SIZE VARCHAR2 (10),
PRODUCT_GROUP NUMBER (4),
PRODUCT_PRICE NUMBER(4),
NO_IN_STOCK NUMBER (4),
REORDER_LEVEL NUMBER (4),
CONSTRAINT PRODUCTS_ID_PK PRIMARY KEY (PRODUCT_ID),
CONSTRAINT FK_GROUP_PLUS_SUPPLIERS_ID FOREIGN KEY (PRODUCT_GROUP) REFERENCES GROUPS_PLUS_SUPPLIERS(GROUP_ID)
);
这是我收到的错误消息:
ORA-02270:此列列表没有匹配的唯一键或主键
以下是我要在群组加供应商中添加的内容:
INSERT INTO GROUPS_PLUS_SUPPLIERS VALUES (1,705,'flavoured oil',5588);
INSERT INTO GROUPS_PLUS_SUPPLIERS VALUES (2,705,'flavoured oil',5509);
INSERT INTO GROUPS_PLUS_SUPPLIERS VALUES (3,800,'spice',5543);
INSERT INTO GROUPS_PLUS_SUPPLIERS VALUES (4,800,'spice',5579);
INSERT INTO GROUPS_PLUS_SUPPLIERS VALUES (5,800,'spice',5584);
任何帮助将不胜感激!
答案 0 :(得分:1)
错误消息显示您缺少的内容。 GROUPS_PLUS_SUPPLIERS(GROUP_ID)
的外键意味着您需要在此列上添加唯一索引。
CREATE TABLE GROUPS_PLUS_SUPPLIERS
(
PRODUCT_GROUP_SUPPLIER_ID NUMBER(3),
GROUP_ID NUMBER(4),
GROUP_NAME VARCHAR2(255),
SUPPLIER_ID NUMBER(4),
CONSTRAINT PRODUCT_GROUP_SUPPLIER_ID_PK PRIMARY KEY (PRODUCT_GROUP_SUPPLIER_ID),
CONSTRAINT FK_SUPPLIER_ID FOREIGN KEY (SUPPLIER_ID) REFERENCES SUPPLIERS (SUPPLIER_ID),
CONSTRAINT AK_GROUP_ID UNIQUE(GROUP_ID)
);
答案 1 :(得分:1)
FK_GROUP_PLUS_SUPPLIERS_ID
表上的约束PRODUCTS
不应引用GROUPS_PLUS_SUPPLIERS(GROUP_ID)
。它应该引用GROUPS_PLUS_SUPPLIERS(PRODUCT_GROUP_SUPPLIER_ID)
。
...
CONSTRAINT FK_GROUP_PLUS_SUPPLIERS_ID FOREIGN KEY (PRODUCT_GROUP) REFERENCES GROUPS_PLUS_SUPPLIERS(PRODUCT_GROUP_SUPPLIER_ID)
...
如果你真的想要成为GROUP_ID
的FK,那么应该有一个GROUP
表,其中GROUP_ID
是主键,你应该参考。< / p>
...
CONSTRAINT FK_GROUP_PLUS_SUPPLIERS_ID FOREIGN KEY (PRODUCT_GROUP) REFERENCES GROUP(GROUP_ID)
...
答案 2 :(得分:1)
由于您的GROUP_ID
列不是唯一的,并且无法对非唯一值进行外键约束(它与哪一行有关?),并且您的GROUPS_PLUS_SUPPLIERS
表也使用了SUPPLIER_ID
,那么你必须有一个复合外键:
CREATE TABLE GROUPS_PLUS_SUPPLIERS (
PRODUCT_GROUP_SUPPLIER_ID NUMBER(3), -- better not to have this column
GROUP_ID NUMBER(4),
GROUP_NAME VARCHAR2(255), -- violates 2nd normal form!
SUPPLIER_ID NUMBER(4),
CONSTRAINT PRODUCT_GROUP_SUPPLIER_ID_PK PRIMARY KEY (PRODUCT_GROUP_SUPPLIER_ID),
CONSTRAINT FK_SUPPLIER_ID FOREIGN KEY (SUPPLIER_ID) REFERENCES SUPPLIERS (SUPPLIER_ID)
-- A new constraint
CONSTRAINT UQ_PRODUCT_GROUP_SUPPLIER_ID_GROUP_ID UNIQUE (SUPPLIER_ID, GROUP_ID)
);
CREATE TABLE PRODUCTS (
PRODUCT_ID NUMBER (4),
PRODUCT_DESCRIPTION VARCHAR2 (255),
PRODUCT_SIZE VARCHAR2 (10),
PRODUCT_GROUP NUMBER (4),
PRODUCT_PRICE NUMBER(4),
NO_IN_STOCK NUMBER (4),
REORDER_LEVEL NUMBER (4),
CONSTRAINT PRODUCTS_ID_PK PRIMARY KEY (PRODUCT_ID),
-- a changed constraint
CONSTRAINT FK_GROUPS_PLUS_SUPPLIERS_SUPPLIER_ID_GROUP_ID
FOREIGN KEY ( SUPPLIER_ID, PRODUCT_GROUP)
REFERENCES GROUPS_PLUS_SUPPLIERS(SUPPLIER_ID, GROUP_ID)
);
我可能不在此建议的基础上,而FK需要指向GROUPS
表,如果它不存在,您需要创建该表。这也是让你的FK指向PRODUCT_GROUP_SUPPLIER_ID
列的可能解决方案,但我保证你这样做会给你带来严重的问题,当你发现要逐个查询你的产品时,你将永远被迫加入另一张桌子。我非常自信地预测,如果你这样做,你会深感遗憾。
数据库设计也存在一些严重问题。
在GROUPS_PLUS_SUPPLIERS
表中查看您想要的更新示例,GROUP_NAME
位于该表中非常糟糕,因为这违反了second normal form。您需要一个GROUPS
表,其中包含GROUP_ID
和GROUP_NAME
列。
GROUPS_PLUS_SUPPLIERS
表似乎是一个多对多连接表,几乎可以肯定不需要自己的ID列。我保证在99%的情况下这是真的,并且对于使用复合键,引用此逻辑关系(SUPPLIER_ID
和GROUP_ID
之间的唯一关系)的任何其他表更好。你会为此感谢我。
NUMBER(4)
似乎非常低。您确定永远不会有超过9999种产品吗?即使是供应商,这听起来也太低了。以后要让自己头疼不已,并使其足够大,以适应真实的企业级场景。
另外,请原谅我,如果我不是免费的,但你的命名方案需要一些工作。我知道一些旧版本的Oracle需要全部大写,并且不能处理小写,所以我想如果你正在使用它,那就忽略那部分。
GroupID
或GroupId
等等。GROUP_ID
,而在另一个表中将其称为PRODUCT_GROUP
。坦率地说,不这样做是荒谬的,并且会导致未来的开发者对你产生混淆和仇恨。在你最好不知道你的地址后,下一个开发人员可以使用这个数据库!GROUPS_PLUS_SUPPLIERS
是不必要的罗嗦。只需使用SUPPLIERS_GROUPS
。Description
,但不要为其他表执行此操作。 (事实上,这就是为什么在我自己的表中我完全停止使用Descr
或Description
,现在只需将列称为表名的单数 - 尽管我的表也是单数的,例如, ProductStatus
表格的名称列为ProductStatus
,而不是ProductStatusDescription
或Description
或其他一些怪物。)以下是我认为更明智的命名方案和数据库设计的样子:
CREATE TABLE Groups (
GroupID NUMBER(4),
GroupName VARCHAR2(255), -- I would normally call this Group but that's reserved
CONSTRAINT PK_Groups PRIMARY KEY (GroupID),
CONSTRAINT UQ_Groups_GroupName UNIQUE (GroupName)
);
CREATE TABLE SupplierGroups (
GroupID NUMBER(4),
SupplierID NUMBER(4),
CONSTRAINT PK_SupplierGroups PRIMARY KEY (SUPPLIER_ID, GROUP_ID),
CONSTRAINT FK_SupplierID FOREIGN KEY (SupplierID) REFERENCES Suppliers (SupplierID),
CONSTRAINT FK_GroupID FOREIGN KEY (GroupID) REFERENCES Groups (GroupID)
);
CREATE TABLE Products (
ProductID NUMBER (4),
ProductDescription VARCHAR2 (255),
Size VARCHAR2 (10),
GroupID NUMBER (4),
Price NUMBER(4),
NoInStock NUMBER (4),
ReorderLevel NUMBER (4),
CONSTRAINT PK_Products PRIMARY KEY (ProductID),
CONSTRAINT FK_Products_SupplierID_GroupID FOREIGN KEY (SupplierID, GroupID)
REFERENCES SupplierGroups (SupplierID, GroupID)
);
答案 3 :(得分:-1)
如果缺乏唯一性是导致错误的真正原因,那么您必须使用复合PK来确保唯一性:
CREATE TABLE GROUPS_PLUS_SUPPLIERS
(
PRODUCT_GROUP_SUPPLIER_ID NUMBER(3),
GROUP_ID NUMBER(4),
GROUP_NAME VARCHAR2(255),
SUPPLIER_ID NUMBER(4),
CONSTRAINT GROUPS_PLUS_SUPPLIERS_PK PRIMARY KEY (PRODUCT_GROUP_SUPPLIER_ID,GROUP_ID,GROUP_NAME,SUPPLIER_ID),
CONSTRAINT FK_SUPPLIER_ID FOREIGN KEY (SUPPLIER_ID) REFERENCES SUPPLIERS (SUPPLIER_ID)
);
这将允许您添加重复的GROUP_ID值,但仍满足所需的匹配唯一性。