为什么 DBMS 说 table 中不存在主键

Why does the DBMS say that the primary key is not present in the table

我是一名 CS 学生,正在学习他的第一门数据库课程,所以在这里我使用 Postgresql 创建一个包含以下 tables 的数据库:员工、项目和 worksOn。

因此,如果您 运行 程序,您可以看到员工和项目 table 都已创建。

但是,worksOn 不是因为它给我以下错误:

SQL Error [23503]: ERROR: insert or update on table "workson" violates foreign key constraint "fk_employee"
Detail: Key (essn)=(222443333) is not present in table "employee"."

我知道人们不会喜欢它,但如果您能提供帮助,我们将不胜感激。另外,考虑到我从来没有处理过数据库,而且我在这上面花了大约一个星期的时间。

DROP TABLE IF EXISTS employee;
DROP TABLE IF EXISTS project;
DROP TABLE IF EXISTS worksOn;

create table employee(
    Ssn bigint generated always as identity,
    Fname varchar(45) not null,
    Lname varchar(45) not null,
    primary key(Ssn)
);

create table project(
    Pname varchar(45) not null,
    Plocation varchar(45) not null,
    Dnum int not null,  
    Pnumber int generated always as identity,
    primary key(Pnumber)
);

create table if not exists worksOn(
    Hours int not null,
    Essn bigint,
    Pno int,
--  index fk_emplyee,
    constraint fk_employee
        foreign key(Essn)
            references employee(Ssn)
            
--  constraint fk_project
--      foreign key(Pno)
--          references project(Pnumber)
--          on delete set null
);

insert into employee (Fname, Lname)
values('Jim', 'Brown');

--insert into project (Pname, Plocation, Dnum)
--values('ProjA', 'Boston', 3);

insert into worksOn (Essn, Pno, Hours)
values(222443333, 1, 20);
        

您的 ssn 列定义为 identity 列,这意味着只要您在插入期间未为其指定值,它就会自动生成。根据您的 SQL 脚本,Jim Brown 的 SSN 值将是 1,而不是您预期的 222443333

您需要从列中删除 identity 属性,然后在插入员工时提供它 table:

create table employee(
    ssn bigint,  --<< no identity!
    fname varchar(45) not null,
    lname varchar(45) not null,
    primary key(ssn)
);
....
....
insert into employee (ssn, fname, lname)
values(222443333, 'Jim', 'Brown');

但是,如果您希望自动生成 SSN,则需要在插入 workson table 时访问最新值:

假设employee.ssn仍然是一个标识列,你可以这样使用:

insert into employee (fname, lname)
values('Jim', 'Brown');

insert into project (pname, plocation, dnum)
values('ProjA', 'Boston', 3);

insert into workson (essn, pno, hours)
values(
   currval(pg_get_serial_sequence('employee', 'ssn')), 
   currval(pg_get_serial_sequence('project', 'number')), 20
);