我更新了我的尝试,保留了一些像CHAR一样的东西,但仍然得到类似的错误:第1行的错误: ORA-02091:交易回滚 ORA-02291:违反了完整性约束(MMM1339.ITEMNO_PHAR_FK) - 未找到父密钥
申请单的外键在不同的供应主键中都有值,所以我不确定为什么还有问题。
CREATE TABLE SUPPLIER
(SUPPLIERNO CHAR(6),
SUPPLIERNAME VARCHAR2(100),
PHONENO VARCHAR2(12),
ADDRESS VARCHAR(100),
FAXNO VARCHAR(12),
CONSTRAINT SUPPLIERNO_SSPL_PK PRIMARY KEY(SUPPLIERNO));
CREATE TABLE SUPPLIES_PHARMACEUTICAL
(ITEMNO CHAR(6),
SUPPLIERNO CHAR(6),
NAME VARCHAR2(25),
DESCRIPTION VARCHAR2(25),
QUANTITYINSTOCK INT,
REORDERLEVEL INT,
COSTPERUNIT DECIMAL(6,2),
DOSAGE VARCHAR2(12),
CONSTRAINT ITEMNO_PHAR_PK PRIMARY KEY(ITEMNO));
CREATE TABLE SUPPLIES_SURGICAL
(ITEMNO CHAR(6),
NAME VARCHAR2(25),
DESCRIPTION VARCHAR2(25),
QUANTITYINSTOCK INT,
REORDERLEVEL INT,
COSTPERUNIT DECIMAL(6,2),
SUPPLIERNO CHAR(6),
CONSTRAINT ITEMNO_SUP_PK PRIMARY KEY(ITEMNO));
CREATE TABLE SUPPLIES_NONSURGICAL
(ITEMNO CHAR(6),
NAME VARCHAR2(25),
DESCRIPTION VARCHAR2(25),
QUANTITYINSTOCK INT,
REORDERLEVEL INT,
COSTPERUNIT DECIMAL(6,2),
SUPPLIERNO CHAR(6),
CONSTRAINT ITEMNO_NONSURG_PK PRIMARY KEY(ITEMNO));
CREATE TABLE STAFF_CHARGENURSE
(STAFFNO CHAR(6),
ADDRESS VARCHAR2(25),
POSITION VARCHAR2(12),
BUDGET DECIMAL(6,2),
SPECIALTY VARCHAR2(12),
CONSTRAINT STAFFNO_CHNURSE_PK PRIMARY KEY(STAFFNO));
CREATE TABLE REQUISITION
(REQNO CHAR(6),
STAFFNO CHAR(6),
STAFFNAME VARCHAR2(25),
WARDNO CHAR(6),
ITEMNO CHAR(6),
QUANTITY INT,
DATEORDERED DATE,
DATERECIEVED DATE,
CONSTRAINT REQ_PK PRIMARY KEY(REQNO));
ALTER TABLE SUPPLIES_PHARMACEUTICAL ADD CONSTRAINT SUPPLIERNO_PHA_FK FOREIGN KEY(SUPPLIERNO) REFERENCES SUPPLIER(SUPPLIERNO) DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE SUPPLIES_SURGICAL ADD CONSTRAINT SUPPLIERNO_SURG_FK FOREIGN KEY(SUPPLIERNO) REFERENCES SUPPLIER(SUPPLIERNO) DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE SUPPLIES_NONSURGICAL ADD CONSTRAINT SUPPLIERNO_NONSURG_FK FOREIGN KEY(SUPPLIERNO) REFERENCES SUPPLIER(SUPPLIERNO) DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE REQUISITION ADD CONSTRAINT STAFFNO_REQ_FK FOREIGN KEY(STAFFNO) REFERENCES STAFF_CHARGENURSE(STAFFNO) DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE REQUISITION ADD CONSTRAINT ITEMNO_PHAR_FK FOREIGN KEY(ITEMNO) REFERENCES SUPPLIES_PHARMACEUTICAL(ITEMNO) DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE REQUISITION ADD CONSTRAINT ITEMNO_SURG_FK FOREIGN KEY(ITEMNO) REFERENCES SUPPLIES_SURGICAL(ITEMNO) DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE REQUISITION ADD CONSTRAINT ITEMNO_NONSURG_FK FOREIGN KEY(ITEMNO) REFERENCES SUPPLIES_NONSURGICAL(ITEMNO) DEFERRABLE INITIALLY DEFERRED;
INSERT INTO REQUISITION VALUES('000001', '345000', 'Julie Wood', '8', '888520', 2, '27-FEB-2018', '15-MAR-2018');
INSERT INTO REQUISITION VALUES('000002', '345000', 'Julie Wood', '8', '923956', 1, '25-FEB-2018', '28-FEB-2018');
INSERT INTO REQUISITION VALUES('000003', '345000', 'Julie Wood', '8', '054802', 3, '20-FEB-2018', '22-FEB-2018');
INSERT INTO SUPPLIES_PHARMACEUTICAL VALUES ('823456', '100001', 'Zanax', 'Anti Depressant', 8, 2, 100.50, '50mg');
INSERT INTO SUPPLIES_PHARMACEUTICAL VALUES ('923956', '100001', 'Zupridol', 'Blood Pressure Treatment', 12, 5, 50, '20mg');
INSERT INTO SUPPLIES_PHARMACEUTICAL VALUES ('003952', '200001', 'Amibreezax', 'Antifungal Ear Wax', 2, 1, 200, '5g');
INSERT INTO SUPPLIES_PHARMACEUTICAL VALUES ('004955', '200001', 'Ambridax', 'Blood Fungus Treatment', 5, 10, 20, '2mg');
INSERT INTO SUPPLIES_SURGICAL VALUES ('054802', 'Scalpel', 'Scalping Tool', 20, 10, 200.42, '100001');
INSERT INTO SUPPLIES_SURGICAL VALUES ('634520', 'Stitches', 'Suture Tool', 100, 10, 2.50, '200001');
INSERT INTO SUPPLIES_NONSURGICAL VALUES ('888520', 'Cart', '5ftx2ftx3ft', 2, 0, 200.00, '100001');
INSERT INTO SUPPLIES_NONSURGICAL VALUES ('000423', 'Tool Holder', 'Holds Inspection Equip.', 4, 2, 50.00, '100001');
INSERT INTO STAFF_CHARGENURSE VALUES('345000', '32 Stark St. Portland, OR', 'Charge Nurse', 8000.99, 'Head Trauma');
INSERT INTO STAFF_CHARGENURSE VALUES('246000', '18 Wilson Rd Portland, OR', 'Charge Nurse', 6000, 'Epidermus');
INSERT INTO SUPPLIER VALUES ('100001','Company A', '503-222-3333', '100 SE Stark Rd Portland, OR', '503-666-4444');
INSERT INTO SUPPLIER VALUES ('200001','Company B', '666-333-4444', '500 SE Bilerica Rd Akron, OH', '666-444-3333');
COMMIT;
答案 0 :(得分:1)
编辑:
将SUPPLIES_SURGICAL
和SUPPLIES_NONSURGICAL
合并为一个SUPPLIES
表,并将PHARMA_DOSAGE
定义为其下的子表。
现在SUPPLIES
行必须是手术或非手术,可以实现为Y / N标志并由检查约束强制执行。 (但是,一个可能的问题是,该模型不会阻止您为手术项目添加剂量。)
在下文中,我已将ITEMNO
设为整数并修正了CHAR
列。您可以考虑查看以NO
结尾的所有列的数据类型,特别是如果它们将按顺序生成。我还会生成所有生成的PK列标识列,但我会将详细信息留给您。
create table supplier
( supplierno integer primary key );
create table supplies
( itemno integer
constraint supplies_pk primary key
, supplierno constraint supplies_supplier_fk references supplier(supplierno)
, name varchar2(25) not null
, description varchar2(25) null
, quantityinstock integer
, reorderlevel integer
, costperunit number(6,2)
, is_surgical varchar2(1) not null
constraint supplies_surgical_yn_chk check(is_surgical in ('Y','N')) );
create table pharma_dosage
( itemno constraint pharma_supplies_fk references supplies(itemno)
constraint pharma_supplies_pk primary key
, dosage varchar2(12) not null );
create table staff_chargenurse
( staffno varchar2(6)
constraint staffno_chnurse_pk primary key
, address varchar2(25)
, position varchar2(12)
, budget number(6,2)
, specialty varchar2(12) );
create table requisition
( reqno varchar2(6)
constraint reqno_pk primary key
, staffno constraint staffno_req_fk references staff_chargenurse(staffno)
, staffname varchar2(25)
, wardno varchar2(6)
, itemno constraint itemno_supplies_fk references supplies(itemno)
, quantity integer
, dateordered date
, daterecieved date );
insert into supplier values ('100001');
insert into supplier values ('200001');
insert into supplies (itemno, supplierno, name, description, quantityinstock, reorderlevel, costperunit, is_surgical) values (823456, '100001', 'Zanax', 'Anti Depressant', 8, 2, 100.50, 'N');
insert into supplies (itemno, supplierno, name, description, quantityinstock, reorderlevel, costperunit, is_surgical) values (923956, '100001', 'Zupridol', 'Blood Pressure Treatment', 12, 5, 50, 'N');
insert into supplies (itemno, supplierno, name, description, quantityinstock, reorderlevel, costperunit, is_surgical) values (003952, '200001', 'Amibreezax', 'Antifungal Ear Wax', 2, 1, 200, 'N');
insert into supplies (itemno, supplierno, name, description, quantityinstock, reorderlevel, costperunit, is_surgical) values (004955, '200001', 'Ambridax', 'Blood Fungus Treatment', 5, 10, 20, 'N');
insert into pharma_dosage (itemno, dosage) values (823456, '50mg');
insert into pharma_dosage (itemno, dosage) values (923956, '20mg');
insert into pharma_dosage (itemno, dosage) values (003952, '5g');
insert into pharma_dosage (itemno, dosage) values (004955, '2mg');
insert into supplies (itemno, name, description, quantityinstock, reorderlevel, costperunit, supplierno, is_surgical) values (054802, 'Scalpel', 'Scalping Tool', 20, 10, 200.42, '100001', 'Y');
insert into supplies (itemno, name, description, quantityinstock, reorderlevel, costperunit, supplierno, is_surgical) values (634520, 'Stitches', 'Suture Tool', 100, 10, 2.50, '200001', 'Y');
insert into supplies (itemno, name, description, quantityinstock, reorderlevel, costperunit, supplierno, is_surgical) values (888520, 'Cart', '5ftx2ftx3ft', 2, 0, 200.00, '100001', 'N');
insert into supplies (itemno, name, description, quantityinstock, reorderlevel, costperunit, supplierno, is_surgical) values (000423, 'Tool Holder', 'Holds Inspection Equip.', 4, 2, 50.00, '100001', 'N');
insert into staff_chargenurse values('345000', '32 Stark St. Portland, OR', 'Charge Nurse', 8000.99, 'Head Trauma');
insert into staff_chargenurse values('246000', '18 Wilson Rd Portland, OR', 'Charge Nurse', 6000, 'Epidermus');
insert into requisition (reqno, staffno, staffname, wardno, itemno, quantity, dateordered, daterecieved) values('000001', '345000', 'Julie Wood', '8', 888520, 2, date '2018-02-27', date '2018-03-15');
insert into requisition (reqno, staffno, staffname, wardno, itemno, quantity, dateordered, daterecieved) values('000002', '345000', 'Julie Wood', '8', 823456, 1, date '2018-02-25', date '2018-02-28');
insert into requisition (reqno, staffno, staffname, wardno, itemno, quantity, dateordered, daterecieved) values('000003', '345000', 'Julie Wood', '8', 054802, 3, date '2018-02-20', date '2018-02-22');
答案 1 :(得分:1)
不幸的是(对于你的DDL代码)我必须同意@William Robertson - 你需要改变你的模型,因此,你需要完全重写你的DDL代码。原因如下:
从原始的DDL代码看一个反向工程模型,我们可以看到REQUISITION有3个(抱歉,4个)父表。这就是为什么它的插入总是因外键违规而失败的原因。你的模特:
以DDL代码的形式说明问题的简化示例可能如下所示:
create table parent1 ( id number primary key ) ; -- analogy: supplies_pharmaceutical
create table parent2 ( id number primary key ) ; -- analogy: supplies_nonsurgical
create table parent3 ( id number primary key ) ; -- analogy: supplies_surgical
create table child ( -- analogy: requisitions
id number primary key
, parentid number
);
alter table child add constraint fkey_parent1
foreign key ( parentid ) references parent1 ( id ) ;
alter table child add constraint fkey_parent2
foreign key ( parentid ) references parent2 ( id ) ;
alter table child add constraint fkey_parent3
foreign key ( parentid ) references parent3 ( id ) ;
begin
insert into parent1 ( id ) values ( 1 ) ;
insert into parent2 ( id ) values ( 2 ) ;
insert into parent3 ( id ) values ( 3 ) ;
end ;
/
因此,填充我们的父表后,只需快速检查:
select 'parent1 (id) -> ' || id from parent1
union all
select 'parent2 (id) -> ' || id from parent2
union all
select 'parent3 (id) -> ' || id from parent3
;
-- result
'PARENT1(ID)->'||ID
parent1 (id) -> 1
parent2 (id) -> 2
parent3 (id) -> 3
一切都好。现在我们想在子表中插入一些行。
insert into child ( id, parentid ) values ( 100, 1 ) ;
-- ORA-02291: integrity constraint (...FKEY_PARENT3) violated - parent key not found
insert into child ( id, parentid ) values ( 101, 2 ) ;
-- ORA-02291: integrity constraint (...FKEY_PARENT3) violated - parent key not found
insert into child ( id, parentid ) values ( 102, 3 ) ;
-- ORA-02291: integrity constraint (...FKEY_PARENT2) violated - parent key not found
您会看到正确的父表不仅仅是“自动选择”。
在William的模型OTOH中,REQUISITION只有一个父母(表)与“供应”有关。哪个应该使插入行更容易...见下文。
答案 2 :(得分:0)
我们需要一些重新排列来抑制 ORA-02291 错误:
创建没有 FOREIGN KEYS 的表格,并在创建所有表格之后, ALTER 表包含 FOREIGN KEYS 。 为了在INSERT操作期间抑制数据不一致,我们需要创建 FOREIGN KEYS 作为 DEFERRABLE INITIALLY DEFERRED (通过以下方式,我们不会遇到任何错误,即使在结束COMMIT发布)。
我认为,您最好将 SUPPLIERNO 列存储为 INT(EGER)或 NUMBER ,而不是 CHAR 。此外,不推荐使用 CHAR 数据类型,最好将它们转换为 VARCHAR2 。
因此,请使用以下一系列操作(在底部,我更改了 REQUISITION 的某些值,以免违反外部约束):
CREATE TABLE SUPPLIER
(SUPPLIERNO INT,
SUPPLIERNAME VARCHAR2(100),
CONSTRAINT SUPPLIERNO_SSPL_PK PRIMARY KEY(SUPPLIERNO));
CREATE TABLE SUPPLIES_PHARMACEUTICAL
(ITEMNO INT,
SUPPLIERNO INT,
NAME VARCHAR2(25),
DESCRIPTION VARCHAR2(25),
QUANTITYINSTOCK INT,
REORDERLEVEL INT,
COSTPERUNIT DECIMAL(6,2),
DOSAGE VARCHAR2(12),
CONSTRAINT ITEMNO_PHAR_PK PRIMARY KEY(ITEMNO));
CREATE TABLE SUPPLIES_SURGICAL
(ITEMNO INT,
NAME VARCHAR2(25),
DESCRIPTION VARCHAR2(25),
QUANTITYINSTOCK INT,
REORDERLEVEL INT,
COSTPERUNIT DECIMAL(6,2),
SUPPLIERNO INT,
CONSTRAINT ITEMNO_SUP_PK PRIMARY KEY(ITEMNO));
CREATE TABLE SUPPLIES_NONSURGICAL
(ITEMNO INT,
NAME VARCHAR2(25),
DESCRIPTION VARCHAR2(25),
QUANTITYINSTOCK INT,
REORDERLEVEL INT,
COSTPERUNIT DECIMAL(6,2),
SUPPLIERNO INT,
CONSTRAINT ITEMNO_NONSURG_PK PRIMARY KEY(ITEMNO));
CREATE TABLE STAFF_CHARGENURSE
(STAFFNO INT,
ADDRESS VARCHAR2(25),
POSITION VARCHAR2(12),
BUDGET DECIMAL(6,2),
SPECIALTY VARCHAR2(12),
CONSTRAINT STAFFNO_CHNURSE_PK PRIMARY KEY(STAFFNO));
ALTER TABLE SUPPLIES_PHARMACEUTICAL ADD CONSTRAINT SUPPLIERNO_PHA_FK FOREIGN KEY(SUPPLIERNO) REFERENCES SUPPLIER(SUPPLIERNO) DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE SUPPLIES_SURGICAL ADD CONSTRAINT SUPPLIERNO_SURG_FK FOREIGN KEY(SUPPLIERNO) REFERENCES SUPPLIER(SUPPLIERNO) DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE SUPPLIES_NONSURGICAL ADD CONSTRAINT SUPPLIERNO_NONSURG_FK FOREIGN KEY(SUPPLIERNO) REFERENCES SUPPLIER(SUPPLIERNO) DEFERRABLE INITIALLY DEFERRED;
INSERT INTO SUPPLIES_PHARMACEUTICAL VALUES (888520, 100001, 'Zanax', 'Anti Depressant', 8, 2, 100.50, '50mg');
INSERT INTO SUPPLIES_PHARMACEUTICAL VALUES (923956, 100001, 'Zupridol', 'Blood Pressure Treatment', 12, 5, 50, '20mg');
INSERT INTO SUPPLIES_PHARMACEUTICAL VALUES (634520, 200001, 'Amibreezax', 'Antifungal Ear Wax', 2, 1, 200, '5g');
INSERT INTO SUPPLIES_PHARMACEUTICAL VALUES (4955, 200001, 'Ambridax', 'Blood Fungus Treatment', 5, 10, 20, '2mg');
INSERT INTO SUPPLIES_SURGICAL VALUES (888520, 'Scalpel', 'Scalping Tool', 20, 10, 200.42, 100001);
INSERT INTO SUPPLIES_SURGICAL VALUES (634520, 'Stitches', 'Suture Tool', 100, 10, 2.50, 200001);
INSERT INTO SUPPLIES_NONSURGICAL VALUES (888520, 'Cart', '5ftx2ftx3ft', 2, 0, 200.00, 100001);
INSERT INTO SUPPLIES_NONSURGICAL VALUES (634520, 'Tool Holder', 'Holds Inspection Equip.', 4, 2, 50.00, 100001);
INSERT INTO STAFF_CHARGENURSE VALUES(345000, '32 Stark St. Portland, OR', 'Charge Nurse', 8000.99, 'Head Trauma');
INSERT INTO STAFF_CHARGENURSE VALUES(246000, '18 Wilson Rd Portland, OR', 'Charge Nurse', 6000, 'Epidermus');
INSERT INTO SUPPLIER VALUES (100001,'Company A');
INSERT INTO SUPPLIER VALUES (200001,'Company B');
CREATE TABLE REQUISITION
(REQNO INT,
STAFFNO INT,
STAFFNAME VARCHAR2(25),
WARDNO INT,
ITEMNO INT,
QUANTITY INT,
DATEORDERED DATE,
DATERECIEVED DATE,
CONSTRAINT REQNO_PK PRIMARY KEY(REQNO),
CONSTRAINT STAFFNO_REQ_FK FOREIGN KEY(STAFFNO) REFERENCES STAFF_CHARGENURSE(STAFFNO),
CONSTRAINT ITEMNO_PHAR_FK FOREIGN KEY(ITEMNO) REFERENCES SUPPLIES_PHARMACEUTICAL(ITEMNO),
CONSTRAINT ITEMNO_SURG_FK FOREIGN KEY(ITEMNO) REFERENCES SUPPLIES_SURGICAL(ITEMNO),
CONSTRAINT ITEMNO_NONSURG_FK FOREIGN KEY(ITEMNO) REFERENCES SUPPLIES_NONSURGICAL(ITEMNO));
INSERT INTO REQUISITION VALUES(1, 345000, 'Julie Wood', 8, 888520, 2, '27-FEB-2018', '15-MAR-2018');
INSERT INTO REQUISITION VALUES(2, 345000, 'Julie Wood', 8, 634520, 1, '25-FEB-2018', '28-FEB-2018');
INSERT INTO REQUISITION VALUES(3, 345000, 'Julie Wood', 8, 634520, 3, '20-FEB-2018', '22-FEB-2018');
COMMIT;
答案 3 :(得分:0)
这个答案与你的问题有关,为什么你的延迟约束的更新定义仍然会导致FK违规。
在尝试提交之前插入行之后:
n_estimators
项select r.reqno, r.itemno
, sp.name as pharmaceutical
, ss.name as surgical
, sn.name as nonsurgical
from requisition r
left join supplies_pharmaceutical sp on sp.itemno = r.itemno
left join supplies_surgical ss on ss.itemno = r.itemno
left join supplies_nonsurgical sn on sn.itemno = r.itemno;
REQNO ITEMNO PHARMACEUTICAL SURGICAL NONSURGICAL
------- ------- --------------- --------------- ---------------
000001 888520 Cart
000002 923956 Zupridol
000003 054802 Scalpel
违反了约束888520
,因为它未在父表ITEMNO_PHAR_FK
中定义:
SUPPLIES_PHARMACEUTICAL
它也违反了ALTER TABLE REQUISITION ADD CONSTRAINT ITEMNO_PHAR_FK
FOREIGN KEY(ITEMNO) REFERENCES SUPPLIES_PHARMACEUTICAL(ITEMNO) ...
,因为ITEMNO_SURG_FK
不在父表888520
中:
SUPPLIES_SURGICAL
等等。每个申请行违反了两个约束。将约束定义为延迟不会改变除错误时间之外的任何内容。
为了满足您的FK定义,每个itemno都需要存在于所有三个耗材表中。
如果您确实需要三个耗材表,则需要三个独立的耗材列,每个列都有自己的FK到相应的表。
(你真的应该将那些ALTER TABLE REQUISITION ADD CONSTRAINT ITEMNO_SURG_FK
FOREIGN KEY(ITEMNO) REFERENCES SUPPLIES_SURGICAL(ITEMNO) ...
列更改为标准字符串类型。CHAR
在Oracle数据库中没有位置,它纯粹是出于奇怪的可移植性和ANSI完整性要求,而不是你的类型实际上应该使用。)