我有兩個表,域和范圍。范圍表參考域。現在,問題是我想要對域表進行軟洗掉(即有一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
uj5u.com熱心網友回復:
Laurenz 的建議不適用于我的用例,因為我確實希望將 保留deleted在外鍵中 - 如果沒有它,有人可能會插入一個參考已洗掉域的范圍,這是我不想要的。
然而,觸發器似乎是正確的方法。我添加了一個觸發器來洗掉范圍,并將外鍵保留為ON UPDATE CASCADE.
現在,當deleted在域中設定為 true 時,級聯更新會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();
uj5u.com熱心網友回復:
我會說你需要一個觸發器:
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。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/361572.html
標籤:PostgreSQL的
