create table Doctor
(
docID INTEGER,
appointID INTEGER not null,
regnum CHAR(6),
doc_name VARCHAR(40),
doc_gender CHAR(1),
qual VARCHAR(80),
primary key (docID),
foreign key (appointID) references Appointment
);
INSERT INTO Doctor
VALUES(1, 1, 'ABC001', 'Steven Arrow', 'M', 'Bachelor of Medicine and Surgery, Deakin University, 1980');
我一直收到错误:
ORA-00001:违反了唯一约束(S3705969.SYS_C001160460)
我做错了什么?
答案 0 :(得分:1)
这确实是重复主键值时出现的错误。解决此问题的最佳方法是使用Oracle 12C +并为主键使用生成的标识列。
一种相对简单的方法是使用序列并确保它用于所有插入:
CREATE SEQUENCE doctor_sequence;
INSERT INTO Doctor( . . . )
VALUES(doctor_sequence.enxtval, 1, 'ABC001', 'Steven Arrow', 'M', 'Bachelor of Medicine and Surgery, Deakin University, 1980');
. . .
是因为您在插入时应明确列出所有列。
我应该指出,在使用序列时,最安全的方法是使用插入触发器,因此您不依赖于应用程序逻辑来使用序列。但是,对于您正在执行的操作,可能不需要触发器。而且,如果您使用的是更新版本的Oracle,那么您只需使用生成的列。
答案 1 :(得分:1)
您应该允许Oracle使用IDENTITY
填充docId
列:
create table Doctor
(
docID INTEGER GENERATED ALWAYS AS IDENTITY not null ,
appointID INTEGER ,
regnum CHAR(6),
doc_name VARCHAR(40),
doc_gender CHAR(1),
qual VARCHAR(80),
primary key (docID),
foreign key (appointID) references Appointment(column_name)
);
INSERT INTO Doctor(col_names, ...) --skip docID
VALUES( 1, 'ABC001', 'Steven Arrow', 'M',
'Bachelor of Medicine and Surgery, Deakin University, 1980');
答案 2 :(得分:0)
在创建表后,DB可能已经在某些列上创建了唯一约束,或者已经存在ID为1的行。您是否尝试在表中查询所有数据?如果在插入之前它是空的,则不应违反唯一约束。尝试DESCRIBE DOCTOR
查看是否存在任何唯一约束。
答案 3 :(得分:0)
ORA-00001
消息表示您正在向列中插入重复值。查看您的create table
语句,我们可以猜测它将是DOC_ID,因此您必须已经插入了一个DOC_ID = 1的行。
那么为什么错误信息如此神秘?
ORA-00001:违反了唯一约束(S3705969.SYS_C001160460)
神秘的名字是因为您创建了主键而没有命名约束,因此Oracle为您生成了一个;约束不是第一类数据库对象(不像表),但它们仍然需要名称。
您可以做的是命名您创建它的约束,例如
create table Doctor
(
docID INTEGER,
appointID INTEGER ,
regnum CHAR(6),
doc_name VARCHAR(40),
doc_gender CHAR(1),
qual VARCHAR(80),
constraint DOCTOR_PK primary key (docID),
constraint DOCTOR_APPOINTMENT_FK foreign key (appointID)
references Appointment(column_name)
);
但如果您发现自己使用缺少名称的模式,那么您可以使用数据字典来发现正在发生的事情
select c.table_name
, decode (c.constraint_type
, 'P', 'Primary key'
, 'U', 'Unique key'
, 'R', 'Foreign key'
, 'C', 'Check') as constraint_type
, cc.column_name
from all_constraints c
join all_cons_columns cc
on cc.owner = c.owner
and cc.table_name = c.table_name
and cc.constraint_name = c.constraint_name
where c.owner = 'S3705969'
and c.constraint_name = 'SYS_C001160460'
order by cc.position
/
顺便说一下,你的外键似乎是错误的方式。一位医生有很多约会,因此您的APPOINTMENT表应该有一个DOCTOR_ID列,其中一个外键引用了DOCTOR表。