Ошибка "ORA-01031: недостаточные привилегии" при вставке в представление

Под именем пользователя "MY_ADMIN" я успешно создал таблицу под названием "NOTIFICATIONS" и представление "V_NOTIFICATIONS". В представлении "V_NOTIFICATIONS" я успешно создал триггер и пакет, который берет то, что пользователь пытается вставить в представление, и вставляет его в таблицу. Триггер и пакет "V_NOTIFICATIONS" также выполняют функции обновления и удаления таблицы, когда пользователь пытается выполнить функции обновления и удаления в представлении.

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

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

ПРОСМОТР: (Когда 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);

3 ответа

Решение

Вставить в представление не удается, потому что вы не можете вставить в ДВОЙНОЙ. Не только ты, но и кто угодно. Пытаться

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

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

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

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

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

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

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

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

Чтобы немного расширить комментарий MJB к исходному сообщению, существует несколько требований (найдите «Заметки об обновляемых представлениях» по этой ссылке), позволяющие обновлять представление. Несколько правил из этого раздела:

  • Все столбцы в представлении должны сопоставляться со столбцом одной таблицы.
  • Представление не может иметь оператор set,DISTINCTоператор, агрегатная или аналитическая функция,GROUP BY,ORDER BYи подобные положения
  • Если представление содержит какие-либо соединения, DML должен влиять только на одну таблицу.

ЕстьALL_UPDATABLE_COLUMNSпредставление словаря данных, которое может перечислять столбцы представления, которое по своей сути является обновляемым, которое можно обновлять, вставлять или удалять.

      @dev01> describe ALL_UPDATABLE_COLUMNS
 Name         Null?    Type
 ------------ --------- --------------
 OWNER         NOT NULL VARCHAR2(128)
 TABLE_NAME    NOT NULL VARCHAR2(128)
 COLUMN_NAME   NOT NULL VARCHAR2(128)
 UPDATABLE              VARCHAR2(3)
 INSERTABLE             VARCHAR2(3)
 DELETABLE              VARCHAR2(3)

Другие вопросы по тегам