【DB笔试面试545】在Oracle中,如何获取用户的权限?

  • 2019 年 10 月 10 日
  • 笔记

题目部分

在Oracle中,如何获取用户的权限?

答案部分

若要获取一个用户的角色、系统权限、对象权限以及列权限,则可以通过以上介绍的数据字典视图来获取也可以通过DBMS_METADATA.GET_GRANTED_DDL来获取。

若使用SYS用户创建了如下的用户LHRSYS并赋予相应的权限:

CREATE USER LHRSYS IDENTIFIED BY LHRSYS;  GRANT  UPDATE (ENAME,SAL) ON  SCOTT.EMP  TO  LHRSYS;  GRANT  UPDATE  (ENAME)  ON  SCOTT.EMP  TO  LHRSYS;  GRANT SELECT ON SCOTT.EMP TO LHRSYS;  GRANT CONNECT TO LHRSYS;  GRANT CREATE JOB TO LHRSYS;  

若通过数据字典来获取权限则可以通过如下的程序来获取LHRSYS的所有权限:

DROP TABLE T_TMP_USER_LHR;  CREATE TABLE   T_TMP_USER_LHR( ID NUMBER, USERNAME VARCHAR2(50), EXEC_SQL VARCHAR2(4000),CREATE_TYPE VARCHAR2(20) );  DROP  SEQUENCE   S_T_TMP_USER_LHR;  CREATE SEQUENCE S_T_TMP_USER_LHR;  BEGIN    FOR CUR IN (SELECT D.USERNAME,                       D.DEFAULT_TABLESPACE,                       D.ACCOUNT_STATUS,                       'create user ' || D.USERNAME || ' identified by ' ||                       D.USERNAME || ' default tablespace ' ||                       D.DEFAULT_TABLESPACE || '  TEMPORARY TABLESPACE  ' ||                       D.TEMPORARY_TABLESPACE || ';' CREATE_USER,                       REPLACE(TO_CHAR(DBMS_METADATA.GET_DDL('USER',D.USERNAME)),CHR(10),'') CREATE_USER1                  FROM DBA_USERS D                 WHERE D.USERNAME NOT IN  ('ANONYMOUS','APEX_030200','APEX_PUBLIC_USER','APPQOSSYS','BI','CTXSYS','DBSNMP','DIP','DMSYS','DVSYS','EXFSYS','FLOWS_FILES','HR','IX','LBACSYS','MDDATA','MDSYS','MGMT_VIEW','OE','OLAPSYS','ORACLE_OCM','ORDDATA','ORDPLUGINS','ORDSYS','OUTLN','OWBSYS','OWBSYS_AUDIT','PM','REMOTE_SCHEDULER_AGENT','SCOTT','SH','SI_INFORMATN_SCHEMA','SI_INFORMTN_SCHEMA','SPATIAL_CSW_ADMIN_USR','SPATIAL_WFS_ADMIN_USR','SYS','SYSMAN','SYSTEM','TSMSYS','WK_TEST','WKPROXY','WKSYS','WMSYS','XDB','XS$NULL')) LOOP        --create user      INSERT INTO T_TMP_USER_LHR        (ID, USERNAME, EXEC_SQL, CREATE_TYPE)      VALUES        (S_T_TMP_USER_LHR.NEXTVAL, CUR.USERNAME, CUR.CREATE_USER, 'USER');        ---system privilege      INSERT INTO T_TMP_USER_LHR        (ID, USERNAME, EXEC_SQL, CREATE_TYPE)        SELECT S_T_TMP_USER_LHR.NEXTVAL,               CUR.USERNAME,               CASE                 WHEN D.ADMIN_OPTION = 'YES' THEN                  'GRANT ' || D.PRIVILEGE || ' TO ' || D.GRANTEE ||                  ' WITH GRANT OPTION ;'                 ELSE                  'GRANT ' || D.PRIVILEGE || ' TO ' || D.GRANTEE || ';'               END PRIV,               'DBA_SYS_PRIVS'          FROM DBA_SYS_PRIVS D         WHERE D.GRANTEE = CUR.USERNAME;        ---role privilege      INSERT INTO T_TMP_USER_LHR        (ID, USERNAME, EXEC_SQL, CREATE_TYPE)        SELECT S_T_TMP_USER_LHR.NEXTVAL,               CUR.USERNAME,               CASE                 WHEN D.ADMIN_OPTION = 'YES' THEN                  'GRANT ' || D.GRANTED_ROLE || ' TO ' || D.GRANTEE ||                  ' WITH GRANT OPTION;'                 ELSE                  'GRANT ' || D.GRANTED_ROLE || ' TO ' || D.GRANTEE || ';'               END PRIV,               'DBA_ROLE_PRIVS'          FROM DBA_ROLE_PRIVS D         WHERE D.GRANTEE = CUR.USERNAME;        ---objects privilege      INSERT INTO T_TMP_USER_LHR        (ID, USERNAME, EXEC_SQL, CREATE_TYPE)        SELECT S_T_TMP_USER_LHR.NEXTVAL,               CUR.USERNAME,               CASE                 WHEN D.GRANTABLE = 'YES' THEN                  'GRANT ' || D.PRIVILEGE || ' ON ' || D.OWNER || '.' ||                  D.TABLE_NAME || ' TO ' || D.GRANTEE ||                  '  WITH GRANT OPTION ;'                 ELSE                  'GRANT ' || D.PRIVILEGE || ' ON ' || D.OWNER || '.' ||                  D.TABLE_NAME || ' TO ' || D.GRANTEE || ';'               END PRIV,               'DBA_TAB_PRIVS'          FROM DBA_TAB_PRIVS D         WHERE D.GRANTEE = CUR.USERNAME;        ---column privilege      INSERT INTO T_TMP_USER_LHR        (ID, USERNAME, EXEC_SQL, CREATE_TYPE)        SELECT S_T_TMP_USER_LHR.NEXTVAL,               CUR.USERNAME,               CASE                 WHEN D.GRANTABLE = 'YES' THEN                  'GRANT ' || D.PRIVILEGE || ' (' || D.COLUMN_NAME || ') ON ' ||                  D.OWNER || '.' || D.TABLE_NAME || ' TO ' || D.GRANTEE ||                  '  WITH GRANT OPTION ;'                 ELSE                  'GRANT ' || D.PRIVILEGE || ' (' || D.COLUMN_NAME || ') ON ' ||                  D.OWNER || '.' || D.TABLE_NAME || ' TO ' || D.GRANTEE || ';'               END PRIV,               'DBA_COL_PRIVS'          FROM DBA_COL_PRIVS D         WHERE D.GRANTEE = CUR.USERNAME ;    END LOOP;    COMMIT;  END;  /  SELECT * FROM T_TMP_USER_LHR;  

可以直接运行EXEC_SQL列来创建用户并赋予相应的权限。另外,可以创建如下的视图:

CREATE OR REPLACE VIEW VW_USER_PRIVS_LHR AS  SELECT D.GRANTEE,         CASE           WHEN D.ADMIN_OPTION = 'YES' THEN            'GRANT ' || D.PRIVILEGE || ' TO ' || D.GRANTEE ||            ' WITH GRANT OPTION ;'           ELSE            'GRANT ' || D.PRIVILEGE || ' TO ' || D.GRANTEE || ';'         END PRIV,         'SYSTEM_GRANT' TYPE,         'DBA_SYS_PRIVS' FROM_VIEW    FROM DBA_SYS_PRIVS D  UNION ALL  SELECT D.GRANTEE,         CASE           WHEN D.ADMIN_OPTION = 'YES' THEN            'GRANT ' || D.GRANTED_ROLE || ' TO ' || D.GRANTEE ||            ' WITH GRANT OPTION;'           ELSE            'GRANT ' || D.GRANTED_ROLE || ' TO ' || D.GRANTEE || ';'         END PRIV,         'SYSTEM_GRANT' TYPE,         'DBA_SYS_PRIVS' FROM_VIEW    FROM DBA_ROLE_PRIVS D  UNION ALL  SELECT D.GRANTEE,         CASE           WHEN D.GRANTABLE = 'YES' THEN            'GRANT ' || D.PRIVILEGE || ' ON ' || D.OWNER || '.' ||            D.TABLE_NAME || ' TO ' || D.GRANTEE || '  WITH GRANT OPTION ;'           ELSE            'GRANT ' || D.PRIVILEGE || ' ON ' || D.OWNER || '.' ||            D.TABLE_NAME || ' TO ' || D.GRANTEE || ';'         END PRIV,         'SYSTEM_GRANT' TYPE,         'DBA_SYS_PRIVS' FROM_VIEW    FROM DBA_TAB_PRIVS D  UNION ALL  SELECT D.GRANTEE,         CASE           WHEN D.GRANTABLE = 'YES' THEN            'GRANT ' || D.PRIVILEGE || ' (' || D.COLUMN_NAME || ') ON ' ||            D.OWNER || '.' || D.TABLE_NAME || ' TO ' || D.GRANTEE ||            '  WITH GRANT OPTION ;'           ELSE            'GRANT ' || D.PRIVILEGE || ' (' || D.COLUMN_NAME || ') ON ' ||            D.OWNER || '.' || D.TABLE_NAME || ' TO ' || D.GRANTEE || ';'         END PRIV,         'COL_GRANT' TYPE,         'DBA_COL_PRIVS' FROM_VIEW    FROM DBA_COL_PRIVS D;  

这样就可以直接查询某个用户的权限了:

SYS@lhrdb> set line 9999  SYS@lhrdb> SELECT * FROM VW_USER_PRIVS_LHR D WHERE D.GRANTEE = 'LHRSYS';  GRANTEE    PRIV                                          TYPE          FROM_VIEW  ---------- --------------------------------------------- ------------ -------------  LHRSYS     GRANT CREATE JOB TO LHRSYS;                   SYSTEM_GRANT DBA_SYS_PRIVS  LHRSYS     GRANT CONNECT TO LHRSYS;                      SYSTEM_GRANT DBA_SYS_PRIVS  LHRSYS     GRANT SELECT ON SCOTT.EMP TO LHRSYS;          SYSTEM_GRANT DBA_SYS_PRIVS  LHRSYS     GRANT UPDATE (ENAME) ON SCOTT.EMP TO LHRSYS;  COL_GRANT    DBA_COL_PRIVS  LHRSYS     GRANT UPDATE (SAL) ON SCOTT.EMP TO LHRSYS;    COL_GRANT    DBA_COL_PRIVS  

通过系统包DBMS_METADATA.GET_DDL也可以获取用户的权限信息,如下所示:

SELECT DBMS_METADATA.GET_DDL('USER', 'LHR') DDL_SQL FROM DUAL  UNION ALL  SELECT DBMS_METADATA.GET_GRANTED_DDL('OBJECT_GRANT', 'LHR') FROM DUAL  UNION ALL  SELECT DBMS_METADATA.GET_GRANTED_DDL('ROLE_GRANT', 'LHR') FROM DUAL  UNION ALL  SELECT DBMS_METADATA.GET_GRANTED_DDL('SYSTEM_GRANT', 'LHR') FROM DUAL;  

将结果拷贝出来简单的用文本编辑工具编辑后即可运行。

另外还可以通过exp或expdp来获取用户的权限,这里不再演示。

& 说明:

有关权限的更多内容可以参考我的BLOG:http://blog.itpub.net/26736162/viewspace-2140775/

本文选自《Oracle程序员面试笔试宝典》,作者:李华荣。