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
.