2010-01-20 10 views
6

Ähnlich wie this question möchte ich wissen, wie alle GRANT-Anweisungen generiert werden, die für alle Rollen in einer Gruppe von Schemas und eine Liste von Rollen ausgegeben werden, deren Namen in "PROXY" enden. Ich mag neu Aussagen wie:GRANTs für Rollen in Schemas neu generieren

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

Der Zweck von einer Entwicklungsdatenbank mit einer Testdatenbank (Oracle 11g) migrieren zu helfen ist. Es gibt einige Tools, die dies automatisch versuchen, aber häufig fehlschlagen.

Irgendwelche Ideen?

+0

Ich denke, du musst es auf die harte Tour machen. Durchlaufen Sie die "All_TAB_PRIVS" und generieren Sie dieses Skript. Eine interessante Frage. Ich würde gerne wissen, ob es möglich ist. – Guru

Antwort

7

Dieses Skript eine Liste aller Tabellenzugriffsrechte auf Rollen ...

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 
/

Hinweis erteilt erzeugt, die ich, nicht die grantee Rollen beschränken, weil Ihre Frage ist in diesem Punkt vage. Möglicherweise müssen Sie der Unterabfrage unter dba_roles einen Filter hinzufügen. Wenn Sie Rollen zu anderen Rollen erteilt haben wollen Sie auch diejenigen holen ...

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 
/

Um die Liste der Rollen zu bekommen ...

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

Beachten Sie, dass diese Skripte nicht generieren Zuschüsse für Systemprivilegien. Auch das Leben ist etwas komplizierter, wenn Sie Verzeichnisobjekte verwenden, weil das ein zusätzliches Schlüsselwort erfordert ...

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) 
/

bearbeitet

In 9i Oracle das DBMS_METADATA Paket eingeführt, die eine Menge von diesen einpackt Arten von Abfragen in einer einfachen PL/SQL-API. Zum Beispiel wird dieser Aufruf ein CLOB mit dem alle Objektprivilegien prorduces zu A gewährt ...

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

Das ist natürlich viel einfacher, als unsere eigenen Rollen.

1

Sie können es mit einigen PL/SQL-Code:

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; 

Sie können es allgemeinere machen die Berechtigungstypen abzubilden Objekttypen oder was-haben-Sie, aber das ist die Grundidee.

Sie müssen EXECUTE IMMEDIATE verwenden, da Sie DDL nicht statisch innerhalb des Verfahrenscodes ausführen können.

+0

Dies würde nur Excecute-Rechte für alle Verfahren Ihres Besitzers gewähren. Wie ich die Frage verstehe, geht es darum, tatsächliche Zuschüsse zu erhalten und ein Skript bereitzustellen, um sie in einem anderen Schema neu zu erstellen. –

+0

Ich zeigte nur die allgemeine Idee. Sie können die SELECT-Abfrage anpassen, um die richtige Liste zu erhalten. – Dan

+0

Warum nicht PL/SQL verwenden? Es scheint ein gutes Werkzeug für diesen Zweck zu sein. – Dan

0

Dies trifft unsere Bedürfnisse:

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; 
+0

Leider funktioniert das nicht. Es enthält nicht den Objektbesitzer im Skript, was von Bedeutung ist, wenn wir mehrere Schemas behandeln. Außerdem ist "girtor" das Konto, das die ursprüngliche Anweisung "grant ..." und nicht das eigene Schema ausgegeben hat. – APC

+0

Fair genug. Ich wollte nur auf potentielle Bereiche hinweisen, die zukünftigen Suchern Probleme bereiten könnten, die durch ein Suchergebnis zu diesem Thread kommen. – APC

0

Ich wollte ein Problem sehr ähnlich wie dieses lösen. Der einzige Unterschied ist, dass ich ein Werkzeug wollte, das generischer und auch DBMS-agnostisch war. Ich wollte das Tool in Produktionsumgebungen anwenden können, und einige der Zieldatenbanken waren nicht Oracle.

was ich kam, war eine Powershell-Funktion, die Parameter Ersetzung durchführt, und generiert ein sich wiederholendes Skript mit einer Sequenz von GRANT-Anweisungen. Die Ausgabe sieht wie folgt aus:

Es gibt zwei Eingaben für mein Werkzeug, eine Vorlagendatei und eine CSV-Datei.Die Vorlagendatei sieht wie folgt aus:

grant $privs 
    on $table 
    to $user; 

Und die CSV-Datei sieht wie folgt aus:

privs,table,user 
ALL,Employees,DBA 
READ,Employees,Analyst 
"READ, WRITE", Employees, Application 
ALL,Departments,DBA 
READ,Departments,"Analyst, Application" 

Das Aufweitwerkzeug sieht wie folgt aus:

<# This function is a table driven template tool. 
    It's a refinement of an earlier attempt. 

    It generates output from a template and 
    a driver table. The template file contains plain 
    text and embedded variables. The driver table 
    (in a csv file) has one column for each variable, 
    and one row for each expansion to be generated. 

    5/13/2015 

#> 

function Expand-csv { 
    [CmdletBinding()] 
    Param(
     [Parameter(Mandatory=$true)] 
     [string] $driver, 
     [Parameter(Mandatory=$true)] 
     [string] $template 
    ) 
    Process 
    { 
     $OFS = "`r`n" 
     $list = Import-Csv $driver 
     [string]$pattern = Get-Content $template 

     foreach ($item in $list) { 
     foreach ($key in $item.psobject.properties) { 
      Set-variable -name $key.name -value $key.value 
      } 
     $ExecutionContext.InvokeCommand.ExpandString($pattern) 
     } 
    } 
} 

Schließlich wird ein Beispielaufruf an die Werkzeug sieht so aus:

Expand-csv demo.csv demo.tem > demo.sql 

Beachten Sie, dass die csv-Dateispezifikation zuerst und die Vorlagendateispezifikation an zweiter Stelle folgt. Beachten Sie, dass die in der Vorlagendatei verwendeten "formalen Parameter" wie Powershell-Variablen aussehen. Das sind sie. Beachten Sie, dass die in der Vorlage verwendeten Namen mit den Namen übereinstimmen, die in der Kopfzeile der CSV-Datei angezeigt werden.

Ich habe tatsächlich einen Vorläufer zu diesem Tool mit einer Vielzahl von SQL-Dialekten und auch mit anderen Zielsprachen als SQL verwendet. Ich habe es sogar verwendet, um ein sich wiederholendes Powershell-Skript zu generieren, das nichts anderes tut, als ein anderes .ps1-Skript immer wieder mit verschiedenen tatsächlichen Parametern aufzurufen.

Es ist nicht das eleganteste Werkzeug der Welt, aber es dient mir gut.

Verwandte Themen