7

この質問と同様にGRANT、一連のスキーマ内のすべてのロールに対して発行されたすべてのステートメントと、名前が「PROXY」で終わるロールのリストを生成する方法を知りたいです。次のようなステートメントを再作成したい:

GRANT SELECT ON TABLE_NAME TO ROLE_NAME;
GRANT EXECUTE ON PACKAGE_NAME TO ROLE_NAME;

目的は、開発データベースからテストデータベース(Oracle 11g)への移行を支援することです。これを自動的に実行しようとするツールがいくつかありますが、失敗することがよくあります。

何か案は?

4

4 に答える 4

10

このスクリプトは、ロールに付与されたすべてのテーブル特権のリストを生成します...

select 'grant '||privilege||' on '||owner||'.'||table_name||' to '||grantee
         ||case when grantable = 'YES' then ' with grant option' else null end
         ||';'
from dba_tab_privs
where owner in ('A', 'B')
and grantee in ( select role from dba_roles )
order by grantee, owner
/

あなたの質問はその点があいまいであるため、被付与者の役割を制限していないことに注意してください。の sub_query にフィルターを追加する必要がある場合がありますdba_roles。他のロールに付与されたロールがある場合は、それらも取得する必要があります...

select 'grant '||granted_role||' to '||grantee
         ||case when admin_option = 'YES' then ' with admin option' else null end
         ||';'
from dba_role_privs
where grantee in ( select role from dba_roles )
order by grantee, granted_role
/

ロールのリストを取得するには ...

select 'create role '||role ||';'
from dba_roles
where role like '%PROXY'
/

これらのスクリプトは、システム権限の付与を生成しないことに注意してください。また、ディレクトリオブジェクトを使用すると、追加のキーワードが必要になるため、生活は少し複雑になります...

select 'grant '||privilege||' on '||owner||'.'||table_name||' to '||grantee
         ||case when grantable = 'YES' then ' with grant option' else null end
         ||';'
from dba_tab_privs
where owner in ('A', 'B')
and grantee in ( select role from dba_roles )
and table_name not in ( select directory_name from dba_directories )
union all
select 'grant '||privilege||' on directory '||table_name||' to '||grantee
         ||case when grantable = 'YES' then ' with grant option' else null end
         ||';'
from dba_tab_privs
where grantee in ( select role from dba_roles )
and table_name  in ( select directory_name from dba_directories )
/

編集

9i では、Oracle は DBMS_METADATA パッケージを導入しました。これは、これらの種類のクエリの多くを単純な PL/SQL API にまとめたものです。たとえば、この呼び出しは、A に付与されたすべてのオブジェクト権限を持つ CLOB を生成します ...

select dbms_metadata.get_granted_ddl('OBJECT_GRANT', 'A') from dual
/

これは明らかに、自分で作成するよりもはるかに簡単です。

于 2010-01-21T04:46:04.907 に答える
1

PL/SQLコードでそれを行うことができます。

TYPE obj_name_type is TABLE OF ALL_OBJECTS%OBJECT_NAME INDEX BY BINARY_INTEGER;
object_names obj_name_type;
i INTEGER;
BEGIN
   SELECT object_name BULK COLLECT INTO object_names FROM ALL_OBJECTS WHERE OWNER = 'whatever' AND object_type = 'PROCEDURE';
   FOR i IN 1 .. object_names.last LOOP
         EXECUTE IMMEDIATE 'GRANT EXECUTE ON ' object_names(i) ' TO ' role_name
   END LOOP;
END;

パーミッションタイプをオブジェクトタイプまたはwhat-have-youにマップすることをより一般的にすることができますが、それが基本的な考え方です。

EXECUTE IMMEDIATE手続き型コード内でDDLを静的に実行することはできないため、を使用する必要があります。

于 2010-01-20T19:03:21.500 に答える
0

これは私たちのニーズを満たしています:

SELECT
  'GRANT ' || p.privilege || ' ON ' || p.table_name || ' TO ' ||
  p.grantee || ';' AS generated_grant
FROM
  dba_tab_privs p
WHERE
  p.grantor IN ( 'SCHEMA_NAME_01', 'SCHEMA_NAME_02' ) AND
  p.grantee IN (
    SELECT DISTINCT
      granted_role
    FROM
      dba_role_privs
    WHERE
      grantee LIKE '%PROXY' AND
      granted_role NOT IN ('CONNECT','AQ_ADMINISTRATOR_ROLE','RESOURCE')
  ) AND
  p.table_name NOT LIKE 'BIN%' AND
  p.table_name NOT LIKE '%$%'
ORDER BY
  p.table_name, p.grantee, p.privilege;
于 2010-01-20T19:42:27.133 に答える