Autoriser l'insertion uniquement depuis un déclencheur

Je suis novice en programmation SQL et je n'ai pas trouvé de réponse à cette question en ligne.

Je travaille avec pl/pgsql et je souhaite atteindre le résultat suivant:

J'ai une table A avec certains attributs. Je suis supposé garder cette table à jour à tout moment - donc chaque fois qu'une modification peut affecter les valeurs de A (dans les autres tables B ou C qui sont liées à A) - un trigger est déclenché qui met à jour les valeurs (dans le de nouvelles valeurs peuvent être insérées dans A, ainsi que les anciennes valeurs peuvent être supprimées). En même temps, je veux empêcher quelqu'un d'insérer des valeurs dans A.

Ce que je veux faire est de créer un trigger qui empêchera l'insertion dans A (en retournant NULL) - mais je ne veux pas que ce trigger soit appelé quand je fais l'insertion depuis un autre Trigger - donc éventuellement - l'insertion dans A ne sera autorisée qu'à partir d'un trigger spécifique.

Comme je l'ai déjà dit, je suis nouveau sur SQL, et je ne sais pas si c'est possible.

2

1 Réponses

Oui, totalement possible.

1. Generally disallow UPDATE to 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 superutilisateurs comme postgres qui ignorent ces restrictions mineures. Attrapez ceux qui se trouvent dans votre fonction de déclenchement sur A avec pg_has_role() :

IF pg_has_role('postgres', 'member') THEN
   RETURN NULL;
END IF;

postgres est un véritable superutilisateur. Note: cela attire aussi d'autres super-utilisateurs, car ils sont membres de tous les rôles, même d'autres super-utilisateurs.

Vous pourriez intercepter les non-superutilisateurs de la même façon (alternative à l'approche REVOKE ).

2. Autorisez UPDATE pour le rôle de démon

Créez un rôle de non-connexion, qui est autorisé à mettre à jour A :

CREATE ROLE a_update;
-- GRANT USAGE ON SCHEMA xyz TO a_update;  -- may be needed, too
GRANT UPDATE ON TABLE A TO a_update;

Create trigger functions on tables B and C, owned by this daemon role and with SECURITY DEFINER. Details here:
Is there a way to disable updates/deletes but still allow triggers to perform them?

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 utiliser contraintes de clés étrangères (en plus) en utilisant ON UPDATE CASCADE .

1
ajouté