2010-06-02 7 views
3

Sous le nom d'utilisateur' MY_ADMIN ', j'ai créé avec succès une table appelée' NOTIFICATIONS 'et une vue appelée' V_NOTIFICATIONS '. Dans la vue 'V_NOTIFICATIONS', j'ai réussi à créer un trigger et un package qui prend ce que l'utilisateur tente d'insérer dans la vue et l'insère dans la table. Le déclencheur et le package 'V_NOTIFICATIONS' exécutent également les fonctions de mise à jour et de suppression sur la table lorsque l'utilisateur tente d'exécuter les fonctions de mise à jour et de suppression sur la vue.Erreur 'ORA-01031: privilèges insuffisants reçus lors de l'insertion dans une vue

Je l'ai fait avec de nombreuses vues dans le projet sur lequel je travaille actuellement, car de nombreuses vues se trouvent au-dessus de nombreuses tables différentes, mais lorsque j'essaie d'insérer un enregistrement dans cette vue, je reçois un ORA-01031: Erreur de privilèges insuffisante.

Je peux insérer directement dans la table en utilisant le même code qui est dans le paquet, mais pas dans la vue. Toute aide à ce sujet serait grandement appréciée. Voici le code demandé:

VIEW: (Lorsque l'Union ci-dessous est commenté, le paquet fonctionne comme prévu)

CREATE OR REPLACE FORCE VIEW "MY_ADMIN"."V_NOTIFICATIONS" AS 
    SELECT N_ID, 
    NOTIFICATION_TYPE, 
    CASE WHEN NOTIFICATION_DESC = 'C' THEN 'Copy' ELSE 'Send to' END NOTIFICATION_DESC, 
    CASE WHEN CONTACT_TYPE = 'D' THEN 'Department' ELSE 'Contact' END CONTACT_TYPE, 
    A.AU_USER_ID, 
    A.CONTACT_NAME, 
    D.DEPARTMENT_ID, 
    D.DEPT_DESC 
    FROM NOTIFICATIONS AN, 
    (SELECT A1.AU_USER_ID, 
      AU.FIRST_NAME || ' ' || AU.LAST_NAME CONTACT_NAME 
     FROM APP_USERS_CONTACT_INFO A1, 
      APPLICATION_USERS AU 
     WHERE A1.AU_USER_ID = AU.USER_ID 
    /*UNION 
    SELECT 0, 
      NULL 
     FROM DUAL*/) A, 
    (SELECT DEPARTMENT_ID, 
      DESCRIPTION DEPT_DESC 
     FROM DEPARTMENTS 
     UNION 
    SELECT 0 DEPARTMENT_ID, 
      NULL DEPT_DESC 
     FROM DUAL) D 
    WHERE NVL(AN.AU_USER_ID,0)  = A.AU_USER_ID 
    AND NVL(AN.D_DEPARTMENT_ID,0) = D.DEPARTMENT_ID;

PAQUET:

CREATE OR REPLACE PACKAGE NOTIFICATIONS_PKG AS 

    PROCEDURE INSERT_NOTIFICATION(P_N_ROW V_NOTIFICATIONS%ROWTYPE); 

END NOTIFICATIONS_PKG; 
/
CREATE OR REPLACE PACKAGE BODY NOTIFICATIONS_PKG AS 

    PROCEDURE INSERT_NOTIFICATION(P_N_ROW V_NOTIFICATIONS%ROWTYPE) IS 

    L_NOTIFICATION_DESC VARCHAR2(1); 
    L_CONTACT_TYPE   VARCHAR2(1); 

    BEGIN 

     CASE P_N_ROW.NOTIFICATION_DESC 
     WHEN 'Copy' THEN 
      L_NOTIFICATION_DESC := 'C'; 
     ELSE 
      L_NOTIFICATION_DESC := 'S'; 
     END CASE; 

     CASE P_N_ROW.CONTACT_TYPE 
     WHEN 'Department' THEN 
      L_CONTACT_TYPE := 'D'; 
     ELSE 
      L_CONTACT_TYPE := 'C'; 
     END CASE; 

     INSERT INTO NOTIFICATIONS VALUES (
     P_N_ROW.N_ID, 
     P_N_ROW.NOTIFICATION_TYPE, 
     L_NOTIFICATION_DESC, 
     L_CONTACT_TYPE, 
     NVL(P_N_ROW.AU_USER_ID, 0), 
     NVL(P_N_ROW.DEPARTMENT_ID, 0), 
     APP_GLOBAL_PKG.GET_AUDIT); 

    END INSERT_AGREEMENT_NOTIFICATION; 
END AGREEMENT_NOTIFICATIONS_PKG;

Le déclencheur est configuré juste passez des informations à ce package pour insérer la ligne. Lors de la tentative d'exécution de la ligne de code suivante, je reçois l'erreur ORA-01031:

INSERT INTO V_AGREEMENT_NOTIFICATIONS VALUES (5781, 'Collateral Request', 'Send to', 'Contact', 797, '797T', 0, null);
+1

est-il possible d'insérer des données dans une vue? Ne le pense pas. – Tom

+1

vous pouvez, mais seulement sous certaines conditions (par exemple, la vue n'est pas une jointure un-à-plusieurs, ou il existe un au lieu de déclencher) – MJB

+0

Cela me semble trop compliqué. Savez-vous que les procédures stockées encapsulent l'accès, de sorte que vous pouvez autoriser l'exécution sur les procédures d'insertion/mise à jour qui effectuent les actions sans accorder l'accès à la table? –

Répondre

5

L'insertion dans la vue échoue car vous ne pouvez pas insérer dans DUAL. Pas seulement toi, mais n'importe qui. Essayez

INSERT INTO DUAL (DUMMY) VALUES ('1') 

pour voir ce qui se passe.

Partagez et appréciez.

+0

Merci. Je ne comprenais pas qu'Oracle verrait cela comme une tentative d'insertion dans Dual même si l'insertion est redirigée via le déclencheur. –

+0

@Patrick: Je m'attends à ce qu'Oracle vérifie les permissions pour pouvoir insérer à travers la vue avant de déclencher des déclencheurs, ce qui est logique - aucun déclencheur de déclenchement si l'utilisateur en question n'a pas d'autorisations sur la vue - mais dans ce cas présence de DUAL foiré les choses. –

0

« Je suis en mesure d'insérer directement dans la table en utilisant le même code qui est dans le paquet, mais pas dans la vue. "

Si vous appelez le paquet directement (c'est-à-dire indirectement via un trigger), cela fonctionne-t-il? Si ce n'est pas le cas, vous pouvez ignorer le côté vue/déclencheur des choses et vous concentrer sur l'emballage. Généralement, si vous pouvez exécuter le SQL directement, mais pas à travers un paquet, c'est parce que vous avez un rôle accordé à votre utilisation avec les privilèges nécessaires. PL/SQL stocké n'a pas de privilèges de rôle.

Si le package fonctionne, il est probable que l'utilisateur n'ait pas le privilège d'insertion sur la vue. Cela peut sembler étrange, car le déclencheur n'a pas de privilèges sur le paquet, mais il s'agirait probablement d'une erreur de compilation, à moins qu'il n'utilise le SQL dynamique.

Les droits INVOKER sur le package peuvent également avoir un effet, car cela signifie qu'il s'exécute avec les privilèges du propriétaire du déclencheur plutôt qu'avec le propriétaire du package. Le propriétaire du déclencheur est probablement le propriétaire de la vue, mais cela peut être différent du propriétaire de la ou des tables.

+0

Lorsque j'appelle directement le paquet, cela fonctionne. De plus, l'utilisateur MY_ADMIN (qui est l'utilisateur auquel je suis connecté) est le propriétaire du paquet, trigger, view et table, donc je devrais avoir tous les privilèges car j'ai accordé tous les privilèges à MY_ADMIN. –