[英]How do the Postgres foreign key 'on update' and 'on delete' options work?
[英]Postgres do on update delete cascade on foreign key
我有兩個表,域和范圍。 范圍表引用域。 現在,問題是我想要對域表進行軟刪除(即,我將一個deleted
的列設置為 true 以將域標記為已刪除 - 這已經在應用程序代碼中處理)。 但我想在范圍表中進行硬刪除。
我知道我可以在外鍵中設置 ON DELETE CASCADE ,但這在這里不起作用,因為我實際上並沒有刪除父表中的一行。 我也不能使用 ON UPDATE CASCADE 因為我不想在子表中更新,我想做一個刪除。 那么我該如何實現呢?
這是最小的架構:
create table domains
(
domain_id varchar(100) not null
constraint domains_pkey
primary key,
deleted boolean default false not null,
constraint domains_deleted_constraint
unique (domain_id, deleted)
);
create table scopes
(
domain_id varchar(100) not null,
scope_name varchar(20) not null,
created_at timestamp default now() not null,
domain_deleted boolean default false not null,
description varchar(500),
constraint scopes_unique_constraint
unique (domain_id, scope_name),
constraint scopes_domain_id_fkey
foreign key (domain_id, domain_deleted) references domains (domain_id, deleted)
on update WHAT TO DO HERE?
);
我在 Postgres 13.4
我會說你需要一個觸發器:
CREATE FUNCTION del_scope() RETURNS trigger
LANGUAGE plpgsql AS
$$BEGIN
IF NEW.deleted = TRUE THEN
DELETE FROM scopes
WHERE domain_id = NEW.domain_id;
END IF;
RETURN NEW;
END;$$;
CREATE TRIGGER BEFORE DELETE ON domains
FOR EACH ROW EXECUTE FUNCTION del_scope();
應將外鍵更改為不包括deleted
。
Laurenz 的建議不適用於我的用例,因為我確實希望將deleted
的內容保留在外鍵中 - 沒有它,有人可能會插入引用已刪除域的 scope ,這是我不想要的。
然而,觸發器似乎是正確的方法。 我添加了一個觸發器來刪除 scope,並將外鍵保留為ON UPDATE CASCADE
。
現在,當域中的deleted
設置為 true 時,級聯更新使 scopes 表中相應行中的domain_deleted
為 true,觸發器只會刪除這些行。
CREATE OR REPLACE FUNCTION delete_scope_on_soft_delete()
RETURNS trigger AS
$func$
BEGIN
DELETE FROM public.scopes WHERE scope_name = OLD.scope_name;
RETURN NULL;
END
$func$ LANGUAGE plpgsql;
CREATE TRIGGER scopes_update_deleted BEFORE UPDATE OF domain_deleted ON scopes
FOR EACH ROW WHEN (new.domain_deleted = true)
EXECUTE FUNCTION delete_scope_on_soft_delete();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.