Привилегии нескольких схем для триггера таблицы в базе данных Oracle

Я пытаюсь написать триггер таблицы, который запрашивает другую таблицу, которая находится вне схемы, в которой будет находиться триггер. Это возможно? Кажется, у меня нет проблем с запросом таблиц в моей схеме, но я получаю:

Error: ORA-00942: table or view does not exist

при попытке запросить таблицы вне моей схемы.

ИЗМЕНИТЬ

Приношу свои извинения за то, что не предоставил максимально полную информацию в первый раз. У меня сложилось впечатление, что этот вопрос был более простым.

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

Учетная запись пользователя, которую я использую для создания триггера, имеет разрешения на независимое выполнение запросов. Фактически, мой триггер напечатал запрос, который я пытаюсь запустить, и смог успешно запустить его самостоятельно.

Я также должен отметить, что я строю запрос динамически, используя оператор EXECUTE IMMEDIATE. Вот пример:

CREATE OR REPLACE TRIGGER MAIN_SCHEMA.EVENTS
BEFORE INSERT
ON MAIN_SCHEMA.EVENTS REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE 
    rtn_count NUMBER := 0;
    table_name VARCHAR2(17) := :NEW.SOME_FIELD;
    key_field VARCHAR2(20) := :NEW.ANOTHER_FIELD;
BEGIN
    CASE
        WHEN (key_field = 'condition_a') THEN
            EXECUTE IMMEDIATE 'select count(*) from OTHER_SCHEMA_A.'||table_name||' where KEY_FIELD='''||key_field||'''' INTO rtn_count;
        WHEN (key_field = 'condition_b') THEN
            EXECUTE IMMEDIATE 'select count(*) from OTHER_SCHEMA_B.'||table_name||' where KEY_FIELD='''||key_field||'''' INTO rtn_count;
        WHEN (key_field = 'condition_c') THEN
            EXECUTE IMMEDIATE 'select count(*) from OTHER_SCHEMA_C.'||table_name||' where KEY_FIELD='''||key_field||'''' INTO rtn_count;
    END CASE;

    IF (rtn_count > 0) THEN
        -- change some fields that are to be inserted
    END IF; 
END;

Сбой триггера при выполнении EXECUTE IMMEDIATE с ранее упомянутой ошибкой.

ИЗМЕНИТЬ

Я провел еще несколько исследований и могу предложить больше разъяснений.

Учетная запись пользователя, которую я использую для создания этого триггера, не является MAIN_SCHEMA или какой-либо из OTHER_SCHEMA_X. Учетная запись, которую я использую (ME), получает привилегии для задействованных таблиц через самих пользователей схемы. Например (USER_TAB_PRIVS):

GRANTOR        GRANTEE TABLE_SCHEMA    TABLE_NAME PRIVILEGE GRANTABLE HIERARCHY
MAIN_SCHEMA    ME       MAIN_SCHEMA    EVENTS     DELETE    NO        NO
MAIN_SCHEMA    ME       MAIN_SCHEMA    EVENTS     INSERT    NO        NO
MAIN_SCHEMA    ME       MAIN_SCHEMA    EVENTS     SELECT    NO        NO
MAIN_SCHEMA    ME       MAIN_SCHEMA    EVENTS     UPDATE    NO        NO
OTHER_SCHEMA_X ME       OTHER_SCHEMA_X TARGET_TBL SELECT    NO          NO

И у меня есть следующие системные привилегии (USER_SYS_PRIVS):

USERNAME   PRIVILEGE            ADMIN_OPTION
ME         ALTER ANY TRIGGER    NO
ME         CREATE ANY TRIGGER   NO
ME         UNLIMITED TABLESPACE NO

И это то, что я нашел в документации Oracle:

Чтобы создать триггер в схеме другого пользователя или сослаться на таблицу в другой схеме из триггера в вашей схеме, вы должны иметь системную привилегию CREATE ANY TRIGGER. С этой привилегией триггер можно создать в любой схеме и связать с любой пользовательской таблицей. Кроме того, пользователь, создающий триггер, также должен иметь привилегию EXECUTE для указанных процедур, функций или пакетов.

Здесь: документ Oracle

Так что мне кажется, что это должно работать, но я не уверен насчет «привилегии EXECUTE», о которой идет речь в документе.


person waltwood    schedule 16.04.2010    source источник
comment
можете ли вы уточнить, можете ли вы выбирать данные из этой таблицы/представления в обычном сеансе SQL вне триггера?   -  person ninesided    schedule 17.04.2010
comment
@девятисторонний: Да. Пожалуйста, смотрите мое редактирование для более подробной информации. @everyone: Пожалуйста, дайте мне знать, если это следует повторно отправить как новый вопрос, поскольку я больше не уверен, что заголовок полностью точен. Спасибо!   -  person waltwood    schedule 18.04.2010
comment
Используете ли вы учетную запись пользователя для создания триггера MAIN_SCHEMA или какую-либо другую учетную запись? Если это другая учетная запись, можете ли вы выполнять эти запросы, если вы войдете в систему как MAIN_SCHEMA?   -  person Jeffrey Kemp    schedule 19.04.2010
comment
Основываясь на вашей новой информации, я предполагаю, что у вас есть привилегии для таблиц OTHER_SCHEMA_% только через роль, а не прямые гранты для учетной записи MAIN_SCHEMA. В этом случае вы сможете запрашивать таблицы в любой интерактивной среде, но не ссылаться на них в программных модулях. Вы можете посмотреть на это в представлении ALL_TAB_PRIVS — GRANTEE должна быть MAIN_SCHEMA, а не ролью, предоставленной MAIN_SCHEMA.   -  person dpbradley    schedule 19.04.2010
comment
@dpbradley: Ваш комментарий побудил меня провести дополнительное исследование, пожалуйста, посмотрите новое редактирование. Спасибо.   -  person waltwood    schedule 19.04.2010


Ответы (3)


Вы должны выполнить это для каждой задействованной таблицы и схемы:

grant select on OTHER_SCHEMA_%.table_name to MAIN_SCHEMA;
person Florin Ghita    schedule 20.04.2010
comment
APC был на правильном пути, и вы попали в цель, вероятно, потому, что я наконец собрал всю необходимую информацию. К сожалению, я не могу проверить, потому что у меня нет необходимых уровней доступа, и я уже сказал администраторам баз данных, что решу проблему в логике своего приложения. Можно было подумать, что они знали об этом с самого начала... В любом случае, спасибо всем! - person waltwood; 20.04.2010

То, что вы испытываете, является особенностью модели безопасности Oracle. Весь смысл использования схем заключается в управлении доступом к данным. Таблицы в моей схеме являются моими, вы даже не можете их видеть, пока я не предоставлю вам права доступа к ним.

Синтаксис довольно прост: схема владельца выдает

grant select, insert on my_table to you
/

В качестве альтернативы учетная запись с привилегией GRANT ANY (например, DBA) может передавать привилегии на любые объекты пользователя.

grant select, insert on apc.my_table to you
/

Получателем прав может быть либо пользователь, либо роль. Однако обратите внимание, что мы можем создавать программные модули — хранимые процедуры, представления, триггеры — только с использованием привилегий, которые были предоставлены непосредственно нашему пользователю.

Итак, если вы попросите другого владельца схемы предоставить вам необходимые привилегии, вы сможете создать свой триггер.

изменить

При ссылке на объект в другой схеме нам нужно квалифицировать объект с помощью имени схемы....

insert into apc.whatever_table  values ...

или же нам нужно создать для него синоним

create synonym whatever for apc.whatever_table;
person APC    schedule 16.04.2010
comment
это тоже было моей мыслью, ждал разъяснений - person ninesided; 17.04.2010

Я чувствую, что кто-то должен добавить очевидное: таблица другой схемы должна быть уточнена именем схемы или необходим частный/общедоступный синоним. Интересно, была ли исходная проблема просто проблемой разрешения имен. Если нет, ответ APC является хорошим объяснением модели безопасности Oracle.

person dpbradley    schedule 17.04.2010
comment
я согласен здесь: выберите * из Anothershema.table - person Randy; 17.04.2010