2010-01-20 28 views
6

Tương tự như this question, tôi muốn biết cách tạo tất cả các câu lệnh GRANT được cấp cho tất cả các vai trò trong một tập hợp các lược đồ và danh sách các vai trò có tên kết thúc bằng "PROXY". Tôi muốn tạo lại các tuyên bố như:Tái tạo GRANT cho vai trò trên các lược đồ

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

Mục đích là giúp di chuyển từ cơ sở dữ liệu phát triển sang cơ sở dữ liệu thử nghiệm (Oracle 11g). Có một số công cụ tự động thực hiện việc này, nhưng thường không thành công.

Bất kỳ ý tưởng nào?

+0

Tôi đoán bạn phải làm điều đó một cách khó khăn. Lặp qua "All_TAB_PRIVS" và tạo tập lệnh này. Một câu hỏi thú vị. Tôi muốn biết nếu có thể. – Guru

Trả lời

7

Kịch bản này tạo ra một danh sách của tất cả các đặc quyền bảng cấp cho vai trò ...

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 
/

Lưu ý rằng tôi không hạn chế vai trò được cấp, vì câu hỏi của bạn là mơ hồ vào thời điểm đó. Bạn có thể cần phải thêm bộ lọc vào sub_query trên dba_roles. Nếu bạn có vai trò cấp cho vai trò khác mà bạn sẽ muốn chọn những quá ...

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 
/

Để có được danh sách các vai trò ...

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

Lưu ý rằng các kịch bản không tạo tài trợ cho các đặc quyền hệ thống. Ngoài ra, cuộc sống là một chút phức tạp hơn nếu bạn sử dụng đối tượng thư mục vì đó đòi hỏi phải có một từ khóa thêm ...

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

chỉnh sửa

Trong 9i Oracle giới thiệu gói DBMS_METADATA mà kết thúc tốt đẹp lên rất nhiều trong số này các loại truy vấn trong một API PL/SQL đơn giản. Ví dụ, cuộc gọi này sẽ prorduces một CLOB với tất cả các đặc quyền đối tượng cấp cho A ...

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

này rõ ràng là đơn giản hơn rất nhiều so với cán của riêng của chúng tôi.

1

Bạn có thể làm điều đó với một số mã 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; 

Bạn có thể làm cho nó chung chung hơn để lập bản đồ các loại phép đối tượng loại hoặc những gì-có-bạn nhưng đó là ý tưởng cơ bản.

Bạn phải sử dụng EXECUTE IMMEDIATE vì bạn không thể chạy DDL tĩnh bên trong mã thủ tục.

+0

Điều này sẽ chỉ cấp quyền cho tất cả các thủ tục của chủ sở hữu của bạn. Khi tôi hiểu câu hỏi đó là về việc nhận trợ cấp thực tế và cung cấp một tập lệnh để tạo lại chúng trên một lược đồ khác. –

+0

Tôi chỉ cho thấy ý tưởng chung. Bạn có thể điều chỉnh truy vấn SELECT để có được danh sách đúng. – Dan

+0

Tại sao không sử dụng PL/SQL? Nó có vẻ như là một công cụ tốt cho mục đích này. – Dan

0

này đáp ứng nhu cầu của chúng tôi:

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

Than ôi điều này không hoạt động. Nó không bao gồm chủ sở hữu đối tượng trong tập lệnh, điều quan trọng khi chúng tôi xử lý nhiều lược đồ. Ngoài ra, 'grantor' là tài khoản đã ban hành lệnh' grant ... 'ban đầu không phải là lược đồ sở hữu. – APC

+0

Đủ công bằng. Tôi chỉ muốn chỉ ra các khu vực tiềm năng có thể gây ra vấn đề cho những người tìm kiếm trong tương lai đến với chủ đề này thông qua kết quả tìm kiếm. – APC

0

Tôi muốn giải quyết một vấn đề rất giống với vấn đề này. Sự khác biệt duy nhất là tôi muốn có một công cụ chung chung hơn, và cũng là DBMS bất khả tri. Tôi muốn có thể áp dụng công cụ này trong môi trường sản xuất và một số cơ sở dữ liệu đích không phải là Oracle.

điều tôi đã nghĩ ra là chức năng Powershell thực hiện thay thế tham số và tạo tập lệnh lặp lại chứa chuỗi các câu lệnh GRANT. Đầu ra trông giống như

grant ALL 
    on Employees 
    to DBA; 




grant READ 
    on Employees 
    to Analyst; 




grant READ, WRITE 
    on Employees 
    to Application; 




grant ALL 
    on Departments 
    to DBA; 




grant READ 
    on Departments 
    to Analyst, Application; 

Có hai đầu vào cho công cụ của tôi, tệp mẫu và tệp csv.Các tập tin mẫu trông như thế này:

grant $privs 
    on $table 
    to $user; 

Và file csv trông như thế này:

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

Các công cụ mở rộng trông như thế này:

<# 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) 
     } 
    } 
} 

Cuối cùng, một cuộc gọi mẫu đến công cụ trông giống như sau:

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

lưu ý rằng thông số tệp csv xuất hiện trước và thông số tệp mẫu đến thứ hai. lưu ý rằng "thông số chính thức" được sử dụng trong tệp mẫu giống như biến Powershell. Đó là những gì họ đang có. lưu ý rằng các tên được sử dụng trong mẫu khớp với tên xuất hiện trong tiêu đề của tệp csv.

Tôi đã thực sự sử dụng tiền thân của công cụ này với một loạt các phương ngữ SQL, và cũng với các ngôn ngữ đích khác với SQL. Tôi thậm chí đã sử dụng nó để tạo ra một kịch bản Powershell lặp đi lặp lại mà không có gì hơn là gọi một tập lệnh .ps1, hơn và hơn nữa, với các thông số thực tế khác nhau.

Nó không phải là công cụ thanh lịch nhất trên thế giới, nhưng nó phục vụ tốt cho tôi.

Các vấn đề liên quan