oracle_脚本获取创建用户语句

本文介绍了一种批量获取Oracle数据库中用户及其相关权限、配额等DDL脚本的方法。通过提供的PL/SQL过程,可以自动生成创建用户的DDL脚本,包括系统权限、对象权限及配额设置等内容。
在某些情况下,我们需要获得数据库用户的创建脚本(包含系统权限,对象权限,配额等相关语句),这些东西如果人工去做绝对是体力活,在asktom网站上看到相关脚本,做了测试和验证,确实很好
-----------------------------------------
-- ###########################################
---------------------------------------------
create or replace procedure GET_CREATE_USER_DDL
 as
cursor get_username is
select username
from dba_users
--where username IN('CHF','XIFENFEI')
;
 
begin
for l_user in get_username loop
 
DBMS_OUTPUT.PUT_LINE('-----------------------');
DBMS_OUTPUT.PUT_LINE('select (case');
DBMS_OUTPUT.PUT_LINE('       when ((selectcount(*)');
DBMS_OUTPUT.PUT_LINE('             from  dba_users');
DBMS_OUTPUT.PUT_LINE('             where username = '''||l_user.username||''') >0)');
DBMS_OUTPUT.PUT_LINE('       then dbms_metadata.get_ddl (''USER'','''||l_user.username||''')');
DBMS_OUTPUT.PUT_LINE('       else  to_clob(''   -- Note: User not found!'')');
DBMS_OUTPUT.PUT_LINE('       end ) "--Extracted_DDL" fromdual');
DBMS_OUTPUT.PUT_LINE('UNION ALL');
 
DBMS_OUTPUT.PUT_LINE('-----------------------');
DBMS_OUTPUT.PUT_LINE('select (case');
DBMS_OUTPUT.PUT_LINE('       when ((selectcount(*)');
DBMS_OUTPUT.PUT_LINE('             from  dba_ts_quotas');
DBMS_OUTPUT.PUT_LINE('             where username = '''||l_user.username||''') >0)');
DBMS_OUTPUT.PUT_LINE('       then dbms_metadata.get_granted_ddl(''TABLESPACE_QUOTA'',
'''||l_user.username||''')');
DBMS_OUTPUT.PUT_LINE('       else  to_clob(''   -- Note: No TS Quotas found!'')');
DBMS_OUTPUT.PUT_LINE('       end )  fromdual');
DBMS_OUTPUT.PUT_LINE('UNION ALL');
 
DBMS_OUTPUT.PUT_LINE('-----------------------');
DBMS_OUTPUT.PUT_LINE('select (case');
DBMS_OUTPUT.PUT_LINE('       when ((selectcount(*)');
DBMS_OUTPUT.PUT_LINE('             from  dba_role_privs');
DBMS_OUTPUT.PUT_LINE('             where grantee = '''||l_user.username||''') >0)');
DBMS_OUTPUT.PUT_LINE('       then dbms_metadata.get_granted_ddl(''ROLE_GRANT'',
'''||l_user.username||''')');
DBMS_OUTPUT.PUT_LINE('       else  to_clob(''   -- Note: No granted roles found!'')');
DBMS_OUTPUT.PUT_LINE('       end ) from dual');
DBMS_OUTPUT.PUT_LINE('UNION ALL');
 
DBMS_OUTPUT.PUT_LINE('-----------------------');
DBMS_OUTPUT.PUT_LINE('select (case');
DBMS_OUTPUT.PUT_LINE('       when ((selectcount(*)');
DBMS_OUTPUT.PUT_LINE('             from  dba_sys_privs');
DBMS_OUTPUT.PUT_LINE('             where grantee = '''||l_user.username||''') >0)');
DBMS_OUTPUT.PUT_LINE('       then dbms_metadata.get_granted_ddl(''SYSTEM_GRANT'',
'''||l_user.username||''')');
DBMS_OUTPUT.PUT_LINE('       else  to_clob(''   -- Note: No System Privilegesfound!'')');
DBMS_OUTPUT.PUT_LINE('       end ) from dual');
DBMS_OUTPUT.PUT_LINE('UNION ALL');
 
DBMS_OUTPUT.PUT_LINE('-----------------------');
DBMS_OUTPUT.PUT_LINE('select (case');
DBMS_OUTPUT.PUT_LINE('       when ((selectcount(*)');
DBMS_OUTPUT.PUT_LINE('             from  dba_tab_privs');
DBMS_OUTPUT.PUT_LINE('             where grantee = '''||l_user.username||''') >0)');
DBMS_OUTPUT.PUT_LINE('       then dbms_metadata.get_granted_ddl(''OBJECT_GRANT'',
'''||l_user.username||''')');
DBMS_OUTPUT.PUT_LINE('       else  to_clob(''   -- Note: No Object Privilegesfound!'')');
DBMS_OUTPUT.PUT_LINE('       end ) from dual');
DBMS_OUTPUT.PUT_LINE('/');
DBMS_OUTPUT.PUT_LINE('----------------------------------------------------------------------');
 
end loop;
end;
/
 
---------------------------------------------
--###########################################
---------------------------------------------
The above proc when called with the foll. will give the SQLsfor all users:
 
---------------------------------------------
-- ###########################################
---------------------------------------------
set pages 50000
set serveroutput on size unlimited
spool /tmp/exec_GET_CREATE_USER_DDL.sql
exec GET_CREATE_USER_DDL
spool off
---------------------------------------------
-- ###########################################
---------------------------------------------
 
These SQLs generated can in turn be run as follows to get themaster-list of all the grants in the database:
 
---------------------------------------------
-- ###########################################
---------------------------------------------
spool /tmp/GET_CREATE_USER_DDL.sql
conn / as sysdba
set long 1000000000
set pages 50000
execDBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',TRUE);
@/tmp/exec_GET_CREATE_USER_DDL.sql
spool off
---------------------------------------------
-- ###########################################
---------------------------------------------
通过这个脚本,我们可以在游标地方限制我们需要获得脚本的用户,而最终得到的/tmp/GET_CREATE_USER_DDL.sql就是我们需要的创建用户的对应脚本.
如果只需要获得一个用户创建相关脚本,只需要执行如下sql即可
execDBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',TRUE);
select (case
       when ((select count(*)
             from  dba_users
             where username = '&&Username') > 0)
       then  dbms_metadata.get_ddl('USER', '&&Username')
       else  to_clob ('  -- Note: User not found!')
       end ) Extracted_DDL from dual
UNION ALL
select (case
       when ((select count(*)
             from  dba_ts_quotas
             where username = '&&Username') > 0)
       then dbms_metadata.get_granted_ddl('TABLESPACE_QUOTA', '&&Username')
       else  to_clob ('  -- Note: No TS Quotas found!')
       end ) from dual
UNION ALL
select (case
       when ((select count(*)
             from  dba_role_privs
             where grantee = '&&Username') > 0)
       then dbms_metadata.get_granted_ddl ('ROLE_GRANT','&&Username')
       else  to_clob ('  -- Note: No granted Roles found!')
       end ) from dual
UNION ALL
select (case
       when ((select count(*)
             from  dba_sys_privs
             where grantee = '&&Username') > 0)
       then dbms_metadata.get_granted_ddl ('SYSTEM_GRANT','&&Username')
       else  to_clob ('  -- Note: No System Privileges found!')
       end ) from dual
UNION ALL
select (case
       when ((select count(*)
             from  dba_tab_privs
             where grantee = '&&Username') > 0)
       then dbms_metadata.get_granted_ddl ('OBJECT_GRANT','&&Username')
       else  to_clob ('  -- Note: No Object Privileges found!')
       end ) from dual
/

<think> 首先,用户的问题是:“我想查找使用Oracle shell脚本获取表空间创建语句的方法”。我需要基于提供的引用来回答这个问题。 回顾提供的引用: - 引用[1]:关于查看表空间大小的SQL语句。 - 引用[2]:提供了一个SQL语句来生成创建表空间的脚本,这是关键引用。 - 引用[3]:关于Oracle调用shell脚本的方法,但内容不相关。 - 引用[4]:似乎无关,甚至提到了动漫角色。 用户的需求是使用Oracle shell脚本获取表空间创建语句。引用[2]直接提供了一个SQL语句,它可以从数据库中生成创建表空间的脚本用户可能想将这个SQL嵌入到一个shell脚本中来自动执行。 我的回答应该: - 使用中文。 - 结构清晰,逐步解决问题。 - 保证真实可靠。 - 符合系统级指令:使用$...$或$$...$$格式,正确LaTeX语法,生成相关问题。 - 在引用的段落末尾添加引用标识,如[^2]。 关键点: - 引用[2]展示了如何用SQL生成创建表空间的语句。 - 我可以解释如何将这个SQL包装在一个shell脚本中。 - 引用[3]提到Oracle调用shell脚本,但不直接相关;或许可以参考,但内容有限。 - 用户提到“Oracle shell脚本”,可能意味着在shell环境中执行SQL*Plus命令或类似的东西。 步骤: 1. **理解需求**:用户想通过shell脚本获取表空间的创建语句。这意味着在shell中运行一个脚本来查询数据库并输出DDL。 2. **解决方案**:使用SQL*Plus在shell脚本中执行SQL查询。参考引用[2]的SQL。 3. **构建脚本**: - 创建一个shell脚本文件。 - 在脚本中使用SQL*Plus连接到Oracle数据库。 - 执行引用[2]中的SQL语句来生成创建脚本。 - 输出结果。 4. **解释引用**:引用[2]提供了SQL,但需要调整以适应特定需求,比如替换表空间名称。 5. **添加引用标识**:在提到引用[2]的地方添加[^2]。 完整脚本示例: - 基于引用[2],SQL是: ```sql SELECT 'CREATE TABLESPACE ' ||D.TABLESPACE_NAME|| ' datafile ''/oradata/orcl/' ||LOWER(D.TABLESPACE_NAME)||'01.dbf'''|| ' size '|| case when (D.total_gb - F.free_gb) > 30 then 30 else round(D.total_gb - F.free_gb + 2) end ||'G autoextend off EXTENT MANAGEMENT LOCAL;' FROM (SELECT TABLESPACE_NAME, ROUND(SUM(BYTES) / (1024 * 1024 * 1024), 2) free_gb FROM SYS.DBA_FREE_SPACE GROUP BY TABLESPACE_NAME) F, (SELECT DD.TABLESPACE_NAME, ROUND(SUM(DD.BYTES) / (1024 * 1024 * 1024), 2) total_gb FROM SYS.DBA_DATA_FILES DD GROUP BY DD.TABLESPACE_NAME) D WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME(+) AND D.TABLESPACE_NAME IN ('需要创建的表空间名称'); ``` - 在shell脚本中,可以这样写: ```bash #!/bin/bash sqlplus -s / as sysdba <<EOF SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF SELECT 'CREATE TABLESPACE ' ||D.TABLESPACE_NAME|| ' datafile ''/oradata/orcl/' ||LOWER(D.TABLESPACE_NAME)||'01.dbf'''|| ' size '|| case when (D.total_gb - F.free_gb) > 30 then 30 else round(D.total_gb - F.free_gb + 2) end ||'G autoextend off EXTENT MANAGEMENT LOCAL;' AS create_statement FROM (SELECT TABLESPACE_NAME, ROUND(SUM(BYTES) / (1024 * 1024 * 1024), 2) free_gb FROM SYS.DBA_FREE_SPACE GROUP BY TABLESPACE_NAME) F, (SELECT DD.TABLESPACE_NAME, ROUND(SUM(DD.BYTES) / (1024 * 1024 * 1024), 2) total_gb FROM SYS.DBA_DATA_FILES DD GROUP BY DD.TABLESPACE_NAME) D WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME(+) AND D.TABLESPACE_NAME IN ('YOUR_TABLESPACE_NAME'); EXIT; EOF ``` 注意:需要替换'YOUR_TABLESPACE_NAME'为实际的表空间名称。 生成相关问题: - 基于主题,可以问: 1. 如何修改脚本以适应不同的表空间路径? 2. 如何自动化创建多个表空间的脚本? 3. 在shell脚本中处理Oracle连接错误的最佳实践? 确保回答结构: - 先介绍方法。 - 提供示例脚本。 - 解释关键部分。 - 添加引用。 - 最后生成相关问题。 </think>### 使用Oracle shell脚本获取表空间创建语句的方法 要使用Shell脚本获取Oracle表空间的创建语句,可以通过SQL*Plus工具在Shell脚本中执行SQL查询,直接生成表空间的DDL(数据定义语言)脚本。以下是详细的步骤和方法,基于引用[2]提供的核心SQL逻辑实现[^2]。 #### 步骤1: 准备核心SQL语句 引用[2]中的SQL语句可以从数据库字典视图中提取表空间信息,并动态生成`CREATE TABLESPACE`语句。关键部分如下: ```sql SELECT 'CREATE TABLESPACE ' || D.TABLESPACE_NAME || ' datafile ''/oradata/orcl/' || LOWER(D.TABLESPACE_NAME) || '01.dbf''' || ' size ' || CASE WHEN (D.total_gb - F.free_gb) > 30 THEN 30 ELSE ROUND(D.total_gb - F.free_gb + 2) END || 'G autoextend off EXTENT MANAGEMENT LOCAL;' FROM (SELECT TABLESPACE_NAME, ROUND(SUM(BYTES) / (1024 * 1024 * 1024), 2) free_gb FROM SYS.DBA_FREE_SPACE GROUP BY TABLESPACE_NAME) F, (SELECT DD.TABLESPACE_NAME, ROUND(SUM(DD.BYTES) / (1024 * 1024 * 1024), 2) total_gb FROM SYS.DBA_DATA_FILES DD GROUP BY DD.TABLESPACE_NAME) D WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME(+) AND D.TABLESPACE_NAME IN ('需要创建的表空间名称'); -- 替换为实际表空间名 ``` - **作用**:查询`DBA_FREE_SPACE`和`DBA_DATA_FILES`视图,计算表空间大小并生成创建语句。 - **输出示例**:`CREATE TABLESPACE USERS datafile '/oradata/orcl/users01.dbf' size 20G autoextend off EXTENT MANAGEMENT LOCAL;` [^2] #### 步骤2: 创建Shell脚本 将上述SQL嵌入Shell脚本中,使用SQL*Plus执行查询并输出结果。以下是完整脚本: ```bash #!/bin/bash # 文件名:generate_tablespace_ddl.sh # 功能:通过Shell脚本生成Oracle表空间的创建语句 # 设置Oracle环境变量(根据实际路径调整) export ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1 export PATH=$PATH:$ORACLE_HOME/bin export ORACLE_SID=orcl # 替换为实际SID # 定义要查询的表空间名称(多个表空间用逗号分隔) TABLESPACE_NAMES="'USERS','SYSAUX'" # 替换为实际名称 # 使用SQL*Plus执行SQL并输出结果 sqlplus -s / as sysdba <<EOF SET PAGESIZE 0 SET FEEDBACK OFF SET HEADING OFF SET VERIFY OFF SELECT 'CREATE TABLESPACE ' || D.TABLESPACE_NAME || ' datafile ''/oradata/orcl/' || LOWER(D.TABLESPACE_NAME) || '01.dbf''' || ' size ' || CASE WHEN (D.total_gb - F.free_gb) > 30 THEN 30 ELSE ROUND(D.total_gb - F.free_gb + 2) END || 'G autoextend off EXTENT MANAGEMENT LOCAL;' FROM (SELECT TABLESPACE_NAME, ROUND(SUM(BYTES) / (1024 * 1024 * 1024), 2) free_gb FROM SYS.DBA_FREE_SPACE GROUP BY TABLESPACE_NAME) F, (SELECT DD.TABLESPACE_NAME, ROUND(SUM(DD.BYTES) / (1024 * 1024 * 1024), 2) total_gb FROM SYS.DBA_DATA_FILES DD GROUP BY DD.TABLESPACE_NAME) D WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME(+) AND D.TABLESPACE_NAME IN ($TABLESPACE_NAMES); EXIT; EOF ``` #### 关键说明 - **脚本权限**:运行前添加执行权限:`chmod +x generate_tablespace_ddl.sh`。 - **连接方式**:`sqlplus -s / as sysdba` 使用操作系统认证(需用户有DBA权限)。如需用户名/密码,替换为 `sqlplus -s username/password@service`。 - **路径调整**: - `datafile`路径(`/oradata/orcl/`)需匹配实际存储位置。 - 表空间名称通过变量`TABLESPACE_NAMES`传入,支持多个名称。 - **输出处理**:脚本直接在终端输出创建语句,可重定向到文件(如 `./generate_tablespace_ddl.sh > create_tablespaces.sql`)。 - **错误处理**:添加`WHENEVER SQLERROR EXIT SQL.SQLCODE`可捕获SQL错误。 #### 注意事项 - **权限要求**:执行脚本用户需有访问`DBA_FREE_SPACE`和`DBA_DATA_FILES`视图的权限(通常为DBA角色)。 - **数据文件大小逻辑**:SQL中`CASE`语句动态计算大小(例如避免超过30GB),可根据业务需求修改。 - **扩展性**:引用[3]提到Oracle调用Shell脚本的方法,可用于进一步自动化(如定时任务)[^3]。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值