可以通过引用表确定的操作来级联更新吗?

时间:2018-08-31 17:43:11

标签: database postgresql merge

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不会传输到引用顾问表。而且,即使确实传输到了​​顾问表,顾问表也将其唯一性约束置于特殊外键上。

对上师来说,有没有办法做到这一点:

  1. 更新专业表的第一个子代:     更新顾问     set speciality_recid ='内部医学'的记录
  2. 在更新顾问表期间,立即使顾问表执行验证新值的操作。也就是说,如果新值产生了一条现有记录,那么顾问表将需要将正确的Recid层叠到其子项中,,然后删除导致唯一性违背的记录。

  3. 级联所有更新之后,并且在发生唯一性违例之前,请删除已更改的记录。

因此,是否有一种方法可以在On Update Cascade上让每个引用表决定需要级联哪些键(如果有)和/或删除记录?

编辑:可以在此处使用“更新规则”吗?

0 个答案:

没有答案