Oui, tout à fait possible.
1. Généralement interdire UPDATE à A
Je fonctionnerais avec des privilèges :
REVOKE ALL ON TABLE A FROM public; -- and from anybody else who might have it
Cela laisse des super-utilisateurs tels que postgres qui ignorent ces humbles restrictions. Attrapez ceux à l'intérieur de votre fonction de déclenchement sur A avec pg_has_role()
:
IF pg_has_role('postgres', 'member') THEN
RETURN NULL;
END IF;
Où postgres est un véritable superutilisateur. Remarque :cela concerne également les autres super-utilisateurs, car ils sont membres de tous les rôles, même les autres super-utilisateurs.
Vous pouvez attraper les non-superutilisateurs de la même manière (alternative au REVOKE approche).
2. Autoriser UPDATE pour le rôle de démon
Créez un rôle sans connexion, qui est autorisé à mettre à jour 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;
Créer des fonctions de déclenchement sur les tables B et C , détenu par ce rôle démon et avec SECURITY DEFINER . Détails :
Ajouter à la fonction de déclenchement sur A :
IF pg_has_role('postgres', 'member') THEN
RETURN NULL;
ELSIF pg_has_role('a_update', 'member') THEN
RETURN NEW;
END IF;
Pour les dépendances 1:1 simples, vous pouvez également travailler avec contraintes de clé étrangère (en plus) en utilisant ON UPDATE CASCADE
.