oracle中获取表空间ddl语句

本文介绍了一个Oracle存储过程,用于自动生成数据库中所有表空间的创建DDL语句。该过程区分了不同类型表空间(如临时、回退和永久表空间)并相应地调整DDL输出。

 参考:

 

http://www.cndw.com/tech/data/2006051167313.asp

 

 

代码:

 

表结构:

-- Create table
create table BAK_DBA_TABLESAPCE
(
  DDL_TXT VARCHAR2(2000)
)
tablespace SYSTEM
  pctfree 10
  pctused 40
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );

存储过程

 

create or replace procedure get_tabspace_ddl
is
  type r_curdf is ref cursor;
  v_tpname varchar2(30);

  cursor v_curtp is select * from dba_tablespaces;
  v_curdf r_curdf;

  v_ddl varchar2(2000);
  v_txt varchar2(2000);
  v_txt1 varchar2(2000);
  v_tp dba_tablespaces%rowtype;
  v_df dba_data_files%rowtype;
  v_count number;
begin

    OPEN V_CURTP;
   
    LOOP
    --<<aa>>
    FETCH v_curtp INTO v_tp;
    EXIT WHEN v_CURtp%NOTFOUND;
   
    V_TPNAME:=v_TP.tablespace_name;
   
    IF v_tp.CONTENTS='TEMPORARY' THEN ---临时表空间
        --DBMS_OUTPUT.PUT_LINE('CREATE TEMPORARY TABLESPACE '||v_tp.tablespace_name||' DATAFILE ');
        v_txt:='CREATE SMALLFILE TEMPORARY TABLESPACE '||v_tp.tablespace_name||' DATAFILE ';
        --insert into bak_dba_tablesapce(ddl_txt) values(v_txt);
       
        SELECT COUNT(*) INTO v_count ---获得游标v_curtp指向的当前表空间包含的临时数据文件数
        FROM DBA_TEMP_FILES
        WHERE tablespace_name=v_tp.tablespace_name;
   
    ELSIF v_tp.CONTENTS='UNDO' THEN ---回退表空间
        -- DBMS_OUTPUT.PUT_LINE('CREATE UNDO TABLESPACE '||v_tp.tablespace_name||' DATAFILE ');
        v_txt:='CREATE SMALLFILE UNDO TABLESPACE '||v_tp.tablespace_name||' DATAFILE ';
        --insert into bak_dba_tablesapce(ddl_txt) values(v_txt);
       
        SELECT COUNT(*) INTO v_count ---获得游标v_curtp指向的当前表空间包含的数据文件数
        FROM DBA_DATA_FILES
        WHERE tablespace_name=v_tp.tablespace_name;
   
    ELSIF v_tp.CONTENTS='PERMANENT' THEN ---普通表空间
      v_txt:='CREATE SMALLFILE TABLESPACE '||v_tp.tablespace_name||' DATAFILE ';
      --insert into bak_dba_tablesapce(ddl_txt) values(v_txt);
   
    END IF;
       
    --if v_tp.CONTENTS='TEMPORARY' THEN ----临时数据文件   
    --OPEN V_CURDF for select * from dba_temp_files where tablespace_name=v_tpname;
    --goto aa;
    --else
    OPEN V_CURDF for select * from dba_data_files where tablespace_name=v_tpname;
    --end if;
   
    LOOP
    FETCH v_curdf INTO v_df; ---获取DATAFILE定义
    EXIT WHEN v_CURdf%NOTFOUND;
   
    --v_txt:= v_txt|| '''' || V_DF.file_name || ''''
   
    IF V_DF.AUTOEXTENSIBLE='YES' THEN
    V_DDL:='AUTOEXTEND ON NEXT '||(V_DF.INCREMENT_BY*8/1024)||'M ';
    ELSE
    V_DDL:='AUTOEXTEND OFF';
    END IF;
   
    IF v_curdf%rowcount=v_count THEN
        v_txt:= v_txt || ''''||v_df.file_name||''''||' SIZE '||(V_DF.BLOCKS*8/1024)||'M REUSE ';
        IF V_DF.AUTOEXTENSIBLE='YES' THEN
             v_txt:= v_txt ||V_DDL || ' MAXSIZE 32767M ';
            
             IF v_tp.LOGGING='LOGGING' THEN
                 v_txt:= v_txt || 'LOGGING';
             END IF;
             IF v_tp.CONTENTS='UNDO' THEN ---回退表空间存储参数
                   v_txt1:= '';
            ELSIF v_tp.CONTENTS='PERMANENT' THEN ---普通表空间存储参数
                v_txt:= v_txt || ' EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO';
            ELSIF v_tp.ALLOCATION_TYPE='UNIFORM' THEN ----统一分区尺寸
               v_txt:= v_txt || ' EXTENT MANAGEMENT '||V_TP.EXTENT_MANAGEMENT||' UNIFORM SIZE '||v_tp.INITIAL_EXTENT/(1024*1024)||'M';                        
            ELSIF v_tp.ALLOCATION_TYPE='SYSTEM' THEN ----系统自动管理分区尺寸
                v_txt:= v_txt || ' EXTENT MANAGEMENT '||V_TP.EXTENT_MANAGEMENT||' AUTOALLOCATE ' ;            
            END IF;
         
            --IF v_tp.SEGMENT_SPACE_MANAGEMENT='AUTO' THEN ----系统自动管理段空间
            --insert into bak_dba_tablesapce(ddl_txt) values('SEGMENT SPACE MANAGEMENT AUTO');
            --END IF;
      END IF;
              --insert into bak_dba_tablesapce(ddl_txt) values(v_txt);
   
    ELSE       
        v_txt:= v_txt || ''''||v_df.file_name||''''||' SIZE '||(V_DF.BLOCKS*8/1024)||'M REUSE ';
        IF V_DF.AUTOEXTENSIBLE='YES' THEN
           --v_txt:= v_txt ||V_DDL||' MAXSIZE 32767M LOGGING EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO , ';
          
           v_txt:= v_txt ||V_DDL || ' MAXSIZE 32767M ';
            
             IF v_tp.LOGGING='LOGGING' THEN
                 v_txt:= v_txt || 'LOGGING';
             END IF;
             IF v_tp.CONTENTS='UNDO' THEN ---回退表空间存储参数
                   v_txt1:= '';
            ELSIF v_tp.CONTENTS='PERMANENT' THEN ---普通表空间存储参数
                v_txt:= v_txt || ' EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO';
                    
            ELSIF v_tp.ALLOCATION_TYPE='UNIFORM' THEN ----统一分区尺寸
               v_txt:= v_txt || ' EXTENT MANAGEMENT '||V_TP.EXTENT_MANAGEMENT||' UNIFORM SIZE '||v_tp.INITIAL_EXTENT/(1024*1024)||'M';                        
            ELSIF v_tp.ALLOCATION_TYPE='SYSTEM' THEN ----系统自动管理分区尺寸
                v_txt:= v_txt || ' EXTENT MANAGEMENT '||V_TP.EXTENT_MANAGEMENT||' AUTOALLOCATE ' ;            
            END IF;
         
            --IF v_tp.SEGMENT_SPACE_MANAGEMENT='AUTO' THEN ----系统自动管理段空间
            --insert into bak_dba_tablesapce(ddl_txt) values('SEGMENT SPACE MANAGEMENT AUTO');
            --END IF;
           
        END IF;
        --insert into bak_dba_tablesapce(ddl_txt) values(v_txt);
       
        IF v_curdf%rowcount > 1 THEN
          v_txt:= v_txt || ' , ' ;
        END IF;     
    END IF;      
   
    END LOOP;
    CLOSE V_CURDF;
    v_txt:= v_txt || '; ' ;
    insert into bak_dba_tablesapce(ddl_txt) values(v_txt);
   
    END LOOP;
    CLOSE V_CURTP;
    COMMIT;
EXCEPTION
    WHEN OTHERS THEN
      if v_curtp%isopen then
      close v_curtp;
      if v_curdf%isopen then
      close v_curdf;
      end if;
      end if;
      ROLLBACK;
      RAISE;      
END get_tabspace_ddl;

 

<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]。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值