Это, скорее всего, более сложной, чем вы даже думать. Оператор GRANT
представляет собой DDL, что означает, что он выдает неявные фиксации, что означает, что вы не можете поместить его в триггер напрямую. Ваш триггер должен будет отправить задание, которое выполнялось в отдельном сеансе после совершения транзакции триггера, которая фактически выполнила бы грант. И это означает, что вам нужно использовать старый пакет DBMS_JOB
, чтобы запланировать работу, так как более современный DBMS_SCHEDULER
также неявно совершает.
Поскольку вы не должны создавать таблицы «на лету» в Oracle, в первую очередь, подходящее место для такого гранта содержится в сценариях сборки, которые вы запускаете для создания таблицы в первую очередь. Опираясь на триггеры, чтобы делать такие вещи, как гранты, обычно имеет тенденцию усложнять сборку, потому что выполнение одного и того же сценария в двух разных средах может генерировать два разных результата из-за различий в триггере.
Если вы решили пойти по этому пути, тем не менее, вы, вероятно, хотите что-то вроде
процедура, которая предоставляет привилегии
CREATE OR REPLACE PROCEDURE grant_select_to_readrole(p_table_name IN VARCHAR2)
AS
BEGIN
EXECUTE IMMEDIATE 'grant select on ' || p_table_name || ' to readrole';
END;
И триггер, который отправляет на работу, которая требует эта процедура
CREATE OR REPLACE TRIGGER osmm_grant_on_creation
AFTER CREATE ON OSMM.SCHEMA
AS
l_jobno PLS_INTEGER;
BEGIN
dbms_job.submit(l_jobno,
'BEGIN grant_select_to_readrole(''' || ora_dict_obj_name || '''); END;',
sysdate + interval '10' second);
END;
Если вы должны были попытаться выпустить DDL в самом триггере уровня схемы, вы получите ошибку
SQL> ed
Wrote file afiedt.buf
1 create or replace trigger after_create_on_scott
2 after create on schema
3 declare
4 begin
5 execute immediate 'grant select on scott.emp to hr';
6* end;
SQL>/
Trigger created.
SQL> create table foo(col1 number);
create table foo(col1 number)
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-30511: invalid DDL operation in system triggers
ORA-06512: at line 3
Любые предложения? Конечно: не делай этого. Разрешенные разрешения являются частью нашей конфигурации базы данных. Таким образом, они должны быть написаны сценариями и храниться в репозитории управления версиями вместе с DDL для создания таблицы. – APC
@ APC - Почему я не хочу этого делать?Я не администратор базы данных и ограниченные знания Oracle, поэтому я боюсь, что ваш ответ не имеет смысла. Есть ли другой способ автоматически предоставлять права выбора для роли для новой таблицы? Потому что делать это вручную - это тяжелая работа, которую мы бы хотели избежать. Триггеры казались очевидным решением, но если есть «лучший» способ, я открыт для него. –
Триггеры - это единственный способ автоматически предоставлять разрешения на объекты по требованию, и это непросто (как показывает ответ Джастина). Это сложно, потому что необычно требовать предоставления одинаковых разрешений для всех таблиц в схеме кому-то другому (роли или пользователю). Чаще всего предоставляется множество привилегий для подмножества таблиц, часто для разных учетных записей. Это сложная логика, чтобы включить триггер. Более общий подход (кроме кодировки cut'n'paste) заключается в использовании метаданных для генерации скриптов. – APC