Tak, całkowicie możliwe.
1. Generalnie nie zezwalaj na UPDATE do A
Działałbym z uprawnieniami:
REVOKE ALL ON TABLE A FROM public; -- and from anybody else who might have it
Pozostają superużytkownicy, tacy jak postgres którzy ignorują te skromne ograniczenia. Złap te wewnątrz funkcji wyzwalacza na A z pg_has_role()
:
IF pg_has_role('postgres', 'member') THEN
RETURN NULL;
END IF;
Gdzie postgres jest prawdziwym superużytkownikiem. Uwaga:obejmuje to również innych superużytkowników, ponieważ są oni członkami każdej roli, nawet innych superużytkowników.
Możesz złapać użytkowników niebędących superużytkownikami w podobny sposób (alternatywa do REVOKE podejście).
2. Zezwól na AKTUALIZACJĘ dla roli demona
Utwórz rolę bez logowania, która może aktualizować A :
CREATE ROLE a_update NOLOGIN;
-- GRANT USAGE ON SCHEMA xyz TO a_update; -- may be needed, too
GRANT UPDATE ON TABLE A TO a_update;
Utwórz funkcje wyzwalacza w tabelach B i C , własność przez tę rolę demona i SECURITY DEFINER . Szczegóły:
Dodaj do funkcji wyzwalacza w A :
IF pg_has_role('postgres', 'member') THEN
RETURN NULL;
ELSIF pg_has_role('a_update', 'member') THEN
RETURN NEW;
END IF;
W przypadku prostych zależności 1:1 możesz również pracować z ograniczenia kluczy obcych (dodatkowo) przy użyciu ON UPDATE CASCADE
.