PostgreSQL 10.1
在完全规范化我的表之后,我现在拥有了重要的信息部分,这些信息在表之间具有唯一的引用标记。
现在的问题是如何正确“合并”不同的记录树。作为示例,我具有以下表定义:
CREATE TABLE speciality
(
recid integer NOT NULL DEFAULT nextval('speciality_recid_seq'::regclass),
speciality_name text COLLATE pg_catalog."default" NOT NULL,
modified timestamp without time zone DEFAULT now(),
CONSTRAINT speciality_pkey PRIMARY KEY (recid),
CONSTRAINT speciality_name_key UNIQUE (speciality_name)
)
CREATE TABLE consultant
(
recid integer NOT NULL DEFAULT nextval('consultant_recid_seq'::regclass),
lastname text COLLATE pg_catalog."default" NOT NULL,
firstname text COLLATE pg_catalog."default" NOT NULL,
modified timestamp without time zone DEFAULT now(),
speciality_recid integer NOT NULL,
CONSTRAINT consultant_pkey PRIMARY KEY (recid),
CONSTRAINT consultant_unique UNIQUE (lastname, firstname, speciality_recid),
CONSTRAINT consultant_speciality_recid_fkey FOREIGN KEY (speciality_recid)
REFERENCES nova.speciality (recid) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT non_empty_firstname CHECK (length(firstname) > 0),
CONSTRAINT non_empty_lastname CHECK (length(lastname) > 0)
)
CREATE TABLE referral_doctor
(
recid integer NOT NULL DEFAULT nextval('referral_doctor_recid_seq'::regclass),
consultant_recid integer,
orderno integer,
office_recid integer,
modified timestamp without time zone NOT NULL DEFAULT now(),
CONSTRAINT referral_doctor_pkey PRIMARY KEY (recid),
CONSTRAINT referral_doctor_consultant_recid_fkey FOREIGN KEY (consultant_recid)
REFERENCES nova.consultant (recid) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT referral_doctor_office_recid_fkey FOREIGN KEY (office_recid)
REFERENCES nova.office (recid) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT referral_doctor_orderno_fkey FOREIGN KEY (orderno)
REFERENCES nova.orders (orderno) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE
)
重要的是,顾问表引用专业表的Recid,referral_doctor引用顾问表的Recid。一切都很好。
问题:为争辩起见,假设专业表具有两个已定义的记录,它们的唯一名称分别为“心脏病学”和“内科医学”。随着时间的流逝,不同的顾问记录将引用这两个专业,而转诊将具有专门针对这两个领域的医生。
现在AMA决定“心脏病”确实应该是“内部医学”:)。
当这些记录被限制为唯一时,如何将专业表中的“心脏病”记录更改为“内部医学”?此外,顾问表使用speciality_recid的外键使其顾问具有唯一性。也就是说,当更改专长表的speciality_recid时,顾问表中也会出现唯一性违规!然后,即使解决了此问题,引荐表现在仍需要引用顾问表中的其他记录!
据我了解,行更新会立即检查主列和唯一列。因此,
Update speciality
set speciality_name = 'Internal Medicine'
where speciality_name = 'Cardiology'
将由于UNIQUE约束而立即失败。做
With t as (
Update speciality
set recid = 'Internal Medicine' recid
where recid = 'Cardiology' recid
)
Delete from speciality
where speciality name ='Cardiology'
也失败,因为删除发生在cte更新(如果有)之前,因此'new'Recid不会传输到引用顾问表。而且,即使确实传输到了顾问表,顾问表也将其唯一性约束置于特殊外键上。
对上师来说,有没有办法做到这一点:
在更新顾问表期间,立即使顾问表执行验证新值的操作。也就是说,如果新值产生了一条现有记录,那么顾问表将需要将正确的Recid层叠到其子项中,,然后删除导致唯一性违背的记录。
级联所有更新之后,并且在发生唯一性违例之前,请删除已更改的记录。
因此,是否有一种方法可以在On Update Cascade上让每个引用表决定需要级联哪些键(如果有)和/或删除记录?
编辑:可以在此处使用“更新规则”吗?