簡體   English   中英

Postgres 在外鍵上更新刪除級聯

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM