Полученная ошибка говорит о том, что вы не можете выполнить DDL (да, grant
- это DDL) подобным образом - это нужно сделать как динамический SQL, используя execute immediate
.
Однако этоне поможет в этом случае , потому что DDL неявно фиксирует , и вы не можете зафиксировать в триггере.
Теперь вы скажете, что можете создатьинициировать как автономная транзакция .Ну, да - вы можете, но это не поможет в этом случае , потому что таблица еще не создана (т.е. она еще не существует).
Вотобходной путь;посмотрим, поможет ли это.В нескольких словах:
- создайте вспомогательную процедуру (чтобы упростить ее), которая фактически будет выполнять
grant
операцию - , позволяющую триггеру отправить задание который вызовет эту процедуру
Вот как: я подключен как Скотт и буду предоставлять привилегии пользователю Майку (поскольку у меня нет ваших пользователей):
SQL> show user
USER is "SCOTT"
SQL>
SQL> -- Auxiliary procedure
SQL> create or replace procedure p_grant (par_str in varchar2) is
2 begin
3 execute immediate par_str;
4 end;
5 /
Procedure created.
SQL> -- Trigger
SQL> create or replace trigger set_permissions
2 after create on schema
3 declare
4 l_job number;
5 l_str varchar2(200);
6 obj_name varchar2(30) := dictionary_obj_name;
7 begin
8 if dictionary_obj_type = 'TABLE'
9 then
10 l_str := 'GRANT SELECT ON ' ||obj_name || ' TO mike';
11 dbms_job.submit
12 (l_job,
13 'begin p_grant(' || chr(39) || l_str || chr(39) ||'); end;',
14 sysdate
15 );
16 end if;
17 end set_permissions;
18 /
Trigger created.
SQL>
Тестирование:
SQL> create table test (id number);
Table created.
SQL> insert into test values (222);
1 row created.
SQL> commit;
Commit complete.
Подключитесь как Майк и проверьте, что он видит:
SQL> connect mike/lion
Connected.
SQL> select * from scott.test;
ID
----------
222
SQL>