«ORA-01031: ошибка недостаточных привилегий», полученная при вставке в представление

Под именем пользователя «MY_ADMIN» я успешно создал таблицу под названием «УВЕДОМЛЕНИЯ» и представление под названием «V_NOTIFICATIONS». В представлении «V_NOTIFICATIONS» я успешно создал триггер и пакет, который принимает то, что пользователь пытается вставить в представление, и вставляет его в таблицу. Триггер и пакет V_NOTIFICATIONS также выполняют функции обновления и удаления в таблице, когда пользователь пытается выполнить функции обновления и удаления в представлении.

Я сделал это со многими представлениями в проекте, над которым я сейчас работаю, так как многие представления находятся поверх многих разных таблиц, однако при попытке вставить запись в это представление я получаю сообщение об ошибке «ORA-01031: недостаточные привилегии». .

Я могу вставить прямо в таблицу, используя тот же код, что и в пакете, но не в представлении. Любая помощь по этому вопросу будет принята с благодарностью. Вот запрошенный код:

VIEW: (когда UNION ниже закомментирован, пакет работает как положено)

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;

УПАКОВКА:

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;

Триггер настроен только для передачи информации в этот пакет для вставки строки. При попытке запустить следующую строку кода я получаю ошибку ORA-01031:

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

person Patrick K    schedule 02.06.2010    source источник
comment
можно ли вставить данные в представление? Не думай так.   -  person Tom    schedule 02.06.2010
comment
вы можете, но только при определенных условиях (например, представление не является объединением «один ко многим» или существует триггер вместо триггера)   -  person MJB    schedule 02.06.2010
comment
Звучит как чрезмерное усложнение для меня. Знаете ли вы, что хранимые процедуры инкапсулируют доступ, поэтому вы можете разрешить выполнение процедур вставки/обновления, которые выполняют действия без предоставления доступа к таблице?   -  person OMG Ponies    schedule 02.06.2010
comment
Триггер, который существует в представлении «V_NOTIFICATIONS», является триггером вместо вставки. Кроме того, я сузил эту ошибку до определенной части представления, где я объединяю: (SELECT DEPT_ID, DEPT_DESC FROM DEPARTMENTS) с (SELECT 0 DEPT_ID, null DEPT_DESC FROM DUAL). Кроме того, является ли это слишком сложным или нет, эта ошибка все еще кажется неуместной.   -  person Patrick K    schedule 03.06.2010
comment
Можете ли вы запустить демо-скрипт. Трудно сказать, возникает ли ошибка 1031 из-за вставки, триггера или пакета.   -  person Gary Myers    schedule 03.06.2010


Ответы (2)


ВСТАВИТЬ в представление не удается, потому что вы не можете вставить в DUAL. Не только ты, но любой. Пытаться

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

чтобы увидеть, что происходит.

Делитесь и наслаждайтесь.

person Bob Jarvis - Reinstate Monica    schedule 04.06.2010
comment
Спасибо. Я не понимал, что Oracle воспримет это как попытку вставки в Dual, хотя у меня вставка перенаправляется через триггер. - person Patrick K; 08.06.2010
comment
@Patrick: я ожидаю, что Oracle проверяет разрешения на возможность вставки через представление перед запуском триггеров, что имеет некоторый смысл — не использовать запуск триггеров, если у рассматриваемого пользователя нет разрешений на представление — но в этом случае присутствие DUAL все испортил. - person Bob Jarvis - Reinstate Monica; 08.06.2010

«Я могу вставить прямо в таблицу, используя тот же код, что и в пакете, но не в представлении».

Если вы вызываете пакет напрямую (т.е. не косвенно через триггер), работает ли он?

Если это не так, вы можете игнорировать сторону просмотра/триггера и сосредоточиться на пакете. Как правило, если вы можете запустить SQL напрямую, но не через пакет, это потому, что вам предоставлена ​​роль с необходимыми привилегиями. Сохраненный PL/SQL не имеет ролевых привилегий.

Если пакет работает, то, вероятно, у пользователя нет прав на вставку в представление. Это может быть что-то странное, например, триггер не имеет привилегий для пакета, но это, вероятно, будет ошибкой компиляции, если только он не использует динамический SQL.

Права INVOKER на пакет также могут иметь эффект, поскольку это будет означать, что он запускается с привилегиями владельца триггера, а не владельца пакета. Владелец триггера, вероятно, является владельцем представления, но он может отличаться от владельца таблицы (таблиц).

person Gary Myers    schedule 03.06.2010
comment
Когда я вызываю пакет напрямую, он работает. Кроме того, пользователь MY_ADMIN (который является пользователем, под которым я подключен) является владельцем пакета, триггера, представления и таблицы, поэтому у меня должны быть все привилегии, поскольку я предоставил все привилегии MY_ADMIN. - person Patrick K; 03.06.2010