2013-06-13 2 views
-1

Мне нужно запросить базу данных Oracle и получить обратно, какие привилегии предоставляются, какие роли и на каких объектах. Потому что я собираюсь либо отменить, либо предоставить привилегии ролям на объектах в соответствии с конфигурациями в системе управления базами данных, которую я создаю.Oracle - запрос, какие привилегии предоставляются, какие роли, на которых объекты

Когда я перебираю объекты, которые собираюсь обрабатывать, мне нужно знать, была ли уже предоставлена ​​какая-либо из прав на этот объект. Это необходимо сделать перед очередью GRANT или REVOKE.

поставщик ODP.NET не поддерживает работу нескольких операторов Oracle, они должны работать по одному или инкапсулируются в BEGIN END блоке (который затем считается одним оператором). Некоторые утверждения даже должны быть помещены внутри операторов EXECUTE IMMEDIATE внутри блока, чтобы он работал.

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

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

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

Я использовал SQLTracker и нашел жаба, используя этот запрос для поиска привилегии на объекты для роли и удалил роли, где положение

SELECT dtp.PRIVILEGE, 
     dtp.grantable ADMIN, 
     dtp.grantee, 
     dtp.grantor, 
     dbo.owner, 
     dbo.object_type, 
     dbo.object_name, 
     dbo.status, 
     '' column_name 
    FROM ALL_TAB_PRIVS dtp, DBA_OBJECTS dbo 
WHERE dtp.TABLE_SCHEMA = dbo.owner AND dtp.table_name = dbo.object_name 
     AND dbo.object_type IN 
       ('TABLE', 
       'VIEW', 
       'PACKAGE', 
       'PROCEDURE', 
       'FUNCTION') 
UNION ALL 
SELECT dcp.PRIVILEGE, 
     dcp.grantable ADMIN, 
     dcp.grantee, 
     dcp.grantor, 
     dbo.owner, 
     dbo.object_type, 
     dbo.object_name, 
     dbo.status, 
     dcp.column_name 
    FROM ALL_COL_PRIVS dcp, DBA_OBJECTS dbo 
WHERE dcp.TABLE_SCHEMA = dbo.owner AND dcp.table_name = dbo.object_name 
     AND dbo.object_type IN 
       ('TABLE', 
       'VIEW', 
       'PACKAGE', 
       'PROCEDURE', 
       'FUNCTION'); 

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

В: Каков наилучший способ запроса, для каких привилегий предоставляются роли, для которых объекты в базе данных Oracle?

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

Есть ли я на правильном пути? Нужно ли его модифицировать? Должен ли я отказаться от него и использовать совершенно другой подход?

ответ

1

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

Tho Я закончил тем, что снял ALL часть из UNION ALL, не получив двойных результатов, давая мне меньший результирующий набор.

SELECT dtp.PRIVILEGE, 
     dtp.grantable ADMIN, 
     dtp.grantee, 
     dtp.grantor, 
     dbo.owner, 
     dbo.object_type, 
     dbo.object_name, 
     dbo.status, 
     '' column_name 
    FROM ALL_TAB_PRIVS dtp, DBA_OBJECTS dbo 
WHERE dtp.TABLE_SCHEMA = dbo.owner AND dtp.table_name = dbo.object_name 
     AND dbo.object_type IN 
       ('TABLE', 
       'VIEW', 
       'PACKAGE', 
       'PROCEDURE', 
       'FUNCTION') 
UNION 
SELECT dcp.PRIVILEGE, 
     dcp.grantable ADMIN, 
     dcp.grantee, 
     dcp.grantor, 
     dbo.owner, 
     dbo.object_type, 
     dbo.object_name, 
     dbo.status, 
     dcp.column_name 
    FROM ALL_COL_PRIVS dcp, DBA_OBJECTS dbo 
WHERE dcp.TABLE_SCHEMA = dbo.owner AND dcp.table_name = dbo.object_name 
     AND dbo.object_type IN 
       ('TABLE', 
       'VIEW', 
       'PACKAGE', 
       'PROCEDURE', 
       'FUNCTION'); 

Запрос может быть очень дорогим, в зависимости от размера базы данных запрашиваемых, поэтому рекомендуется только один раз запрос или использовать больше, где положение, чтобы сузить набор результатов.

1

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

create or replace procedure revoke_priv (
    object_owner all_objects.owner%type , 
    object_name  all_objects.object_name%type , 
    privilege  all_tab_privs.privilege%type , 
    role_name  role_tab_privs.role%type) 
authid current_user 
as 
    err number; 
    stmt varchar2(4001); 
begin 
    stmt := 'revoke ' || privilege || ' on ' || object_owner || '.' || object_name ||' from ' || role_name; 
    execute immediate stmt; 
exception when others then 
    err := SQLCODE; 
    if (err = -1927) then 
     dbms_output.put_line('the privilege does not exists for the role'); 
    else 
     raise; 
    end if; 
end; 
/

и это сценарий

SQL>create role my_role; 

Role created. 

SQL>grant select on scott.dept to my_role; 

Grant succeeded. 

SQL>select role , owner , table_name , PRIVILEGE from role_tab_privs where role = 'MY_ROLE'; 

ROLE       OWNER       TABLE_NAME      PRIVILEGE 
------------------------------ ------------------------------ ------------------------------ ---------------------------------------- 
MY_ROLE      SCOTT       DEPT       SELECT 

SQL>revoke select on scott.dept from my_role; 

Revoke succeeded. 

SQL>revoke select on scott.dept from my_role; 
revoke select on scott.dept from my_role 
* 
ERROR at line 1: 
ORA-01927: cannot REVOKE privileges you did not grant 

SQL>grant select on scott.dept to my_role; 

Grant succeeded. 

SQL>exec revoke_priv('SCOTT','DEPT','SELECT','MY_ROLE'); 

PL/SQL procedure successfully completed. 

SQL>select role , owner , table_name , PRIVILEGE from role_tab_privs where role = 'MY_ROLE'; 

no rows selected 

SQL>exec revoke_priv('SCOTT','DEPT','SELECT','MY_ROLE'); 
the privilege does not exists for the role 

PL/SQL procedure successfully completed. 

SQL>drop role my_role; 

Role dropped. 
+0

Значит, вы говорите достаточно, чтобы запрашивать только таблицу ROLE_TAB_PRIVS? – furier

+0

Это единственный способ получить роль прив. любой другой способ неявно использует эту таблицу в любом случае. – haki

+0

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

Смежные вопросы