繁体   English   中英

PostgreSQL没有唯一约束错误

[英]postgresql no unique constraint error

我为这个模式得到这个错误:

ERROR:  there is no unique constraint matching given keys for referenced table "abteilung"

我做错了什么? 编辑:现在我将列krankenhaus添加到表mitarbeiter并更改alter table命令,但是我得到相同的错误...

模式:

CREATE TABLE Person (
    svnr VARCHAR(40) PRIMARY KEY,
    anschrift VARCHAR(40) NOT NULL,
    name VARCHAR(20) NOT NULL
);

BEGIN;

CREATE TABLE Mitarbeiter (
    svnr VARCHAR(40) PRIMARY KEY REFERENCES Person(svnr),
    beschaeftigt_seit DATE NOT NULL,
    gehalt NUMERIC(5,2),
    CHECK(gehalt > 0),
    abteilung INTEGER NOT NULL,
    krankenhaus INTEGER NOT NULL
);

CREATE TABLE Krankenhaus (
    kid INTEGER PRIMARY KEY DEFAULT nextval('seq_krankenhaus'),
    anschrift VARCHAR(40) NOT NULL,
    name VARCHAR(20) NOT NULL,
    geleitet_von VARCHAR(40) REFERENCES Mitarbeiter(svnr) DEFERRABLE INITIALLY DEFERRED
);

CREATE TABLE Abteilung (
    abid INTEGER DEFAULT nextval('seq_abteilung'),
    name VARCHAR(40) NOT NULL,
    anschrift VARCHAR(40) NOT NULL,
    koordiniert VARCHAR(40) REFERENCES Mitarbeiter(svnr) DEFERRABLE INITIALLY DEFERRED,
    krankenhaus INTEGER REFERENCES Krankenhaus(kid),
    PRIMARY KEY (abid, krankenhaus)
);

ALTER TABLE Mitarbeiter ADD CONSTRAINT fk_abteilung FOREIGN KEY (abteilung, krankenhaus) REFERENCES Abteilung(abid, krankenhaus) DEFERRABLE INITIALLY DEFERRED;

COMMIT;

Abteilung的主键是(abid, krankenhaus) 由于外部引用仅引用一行,因此您还需要在外键约束定义中同时使用列。

但是当你没有列krankenhaus在你的表Mitarbeiter你不能引用Abteilung

您或者需要将Abteilung的主键减小为(abid) (因为无论如何它都是生成的人工键,这都是可能的),或者在Mitarbeiter表中添加一列Krankenhaus

这应该工作:

CREATE TABLE person (
   svnr text PRIMARY KEY
 , anschrift text NOT NULL
 , name text NOT NULL
);

CREATE TABLE mitarbeiter (
   svnr text PRIMARY KEY REFERENCES person
 , beschaeftigt_seit date NOT NULL
 , gehalt numeric(5,2)
 , abid int NOT NULL
 , CHECK(gehalt > 0)
);

CREATE TABLE krankenhaus (
   kid serial PRIMARY KEY
 , anschrift text NOT NULL
 , name text NOT NULL
 , geleitet_von text REFERENCES mitarbeiter(svnr) DEFERRABLE INITIALLY DEFERRED
);

CREATE TABLE abteilung (
   abid serial PRIMARY KEY
 , kid INTEGER REFERENCES krankenhaus(kid)
 , koordiniert text REFERENCES mitarbeiter(svnr) DEFERRABLE INITIALLY DEFERRED
 , name text NOT NULL
 , anschrift text NOT NULL
);

ALTER TABLE mitarbeiter
   ADD CONSTRAINT fk_abteilung FOREIGN KEY (abid)
   REFERENCES abteilung(abid) DEFERRABLE INITIALLY DEFERRED;

要点

  • serial列用于替代PK:

  • 请勿对字符串长度使用具有任意限制的varchar(n) ,除非您确实需要强制执行最大长度且该长度不会改变。 细节:

  • 一起去的只是abid作为主键abteilung 是包含在FK约束冗余列相关的应用程序,但是这是你的模型确实现在不是:

  • 无需为部分代码使用显式事务( BEGIN ... COMMIT )。

  • 这种循环引用的真正困难在于输入和更改数据。 您可能使FK约束DEFERRABLE INITIALLY DEFERRED -这将使某些查询变得相当
    如果将相关行上的INSERT / UPDATE包装到可修改数据的CTE中 ,则可以使用普通的默认IMMEDIATE FK约束:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM