免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1744 | 回复: 0
打印 上一主题 下一主题

从已有数据库中获得表结构的几种方法,总结篇 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-05-20 13:10 |只看该作者 |倒序浏览
1、使用工具
      我用过toad,对于单个表来说很方便,而且很多项目可以定制,但是如果获取的表结构过多,或者表的语句太大,取表结构的速度会非常慢,我取过4000多行的单表建表语句,需要10多分钟。其他工具我没用过,但我想大同小异

2、exp/imp
      exp时带上 rows=n 的参数,导出的就只有表结构
      imp时带上 show=y 和 log 选项,可以查看到建表语句,但是其中的双引号和存储类子句我不知道如何去掉,只能通过脚本替换

3、DBMS_METADATA.GET_DDL
     例如:SELECT DBMS_METADATA.get_ddl ('TABLE', 'FOO','USER')  FROM DUAL;
                 第一个参数:表示对象类型,有TABLE,INDEX,VIEW等
                 第二个参数:表示数据库对象,具体就是表名或者索引名
                 第三个参数:表示数据库对象的属主
      需要注意的是,这个函数有一个BUG,需要打一个补丁才可以用

得到的 DDL有的时候似乎太详细了一些
很多Storage / FREELIST之类的语句可能并不是您想要的,可以在当前会话中提交如下语句:
exec dbms_metadata.set_transform_param(dbms_metadata.session_transform,'PRETTY', true);
exec dbms_metadata.set_transform_param(dbms_metadata.session_transform,'SEGMENT_ATTRIBUTES', true);
exec dbms_metadata.set_transform_param(dbms_metadata.session_transform,'STORAGE', false);
exec dbms_metadata.set_transform_param(dbms_metadata.session_transform,'TABLESPACE', true);
exec dbms_metadata.set_transform_param(dbms_metadata.session_transform,'CONSTRAINTS', false);
exec dbms_metadata.set_transform_param(dbms_metadata.session_transform,'REF_CONSTRAINTS', false);
exec dbms_metadata.set_transform_param(dbms_metadata.session_transform,'CONSTRAINTS_AS_ALTER', false);


抽取当前模式下所有表的DDL:
SELECT DBMS_METADATA.GET_DDL('TABLE',u.table_name)
     FROM USER_ALL_TABLES u
     WHERE u.nested='NO'
     AND (u.iot_type is null or u.iot_type='IOT');
      



4、自己写脚本
      主要用到的代码表有user_tables/user_tab_columns



一、exp/imp的例子:
c:\>;exp userid=scott/tiger owner=scott
c:\>;imp userid=scott/tiger full=y indexfile=scott.sql
注意着时import并没有真正写入数据库,而是将DDL写在scott.sql里。
scott.sql:
REM  CREATE TABLE "SCOTT"."BONUS" ("ENAME" VARCHAR2(10), "JOB"  
REM  VARCHAR2(9), "SAL" NUMBER, "COMM" NUMBER) PCTFREE 10 PCTUSED 40  
REM  INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 FREELISTS 1 FREELIST  
REM  GROUPS 1) TABLESPACE "USERS" LOGGING NOCOMPRESS ;
REM  ... 0 rows
REM  CREATE TABLE "SCOTT"."DEPT" ("DEPTNO" NUMBER(2, 0), "DNAME"  
REM  VARCHAR2(14), "LOC" VARCHAR2(13)) PCTFREE 10 PCTUSED 40 INITRANS 1  
REM  MAXTRANS 255 STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS 1)  
REM  TABLESPACE "USERS" LOGGING NOCOMPRESS ;
REM  ... 4 rows
REM  CREATE TABLE "SCOTT"."DUMMY" ("DUMMY" NUMBER) PCTFREE 10 PCTUSED 40  
REM  INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 FREELISTS 1 FREELIST  
REM  GROUPS 1) TABLESPACE "USERS" LOGGING NOCOMPRESS ;
REM  ... 1 rows
REM  CREATE TABLE "SCOTT"."EMP" ("EMPNO" NUMBER(4, 0) NOT NULL ENABLE,  
REM  "ENAME" VARCHAR2(10), "JOB" VARCHAR2(9), "MGR" NUMBER(4, 0),  
REM  "HIREDATE" DATE, "SAL" NUMBER(7, 2), "COMM" NUMBER(7, 2), "DEPTNO"  
REM  NUMBER(2, 0)) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255  
REM  STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS 1) TABLESPACE  
REM  "USERS" LOGGING NOCOMPRESS ;
REM  ... 14 rows
REM  CREATE TABLE "SCOTT"."SALGRADE" ("GRADE" NUMBER, "LOSAL" NUMBER,  
REM  "HISAL" NUMBER) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255  
REM  STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS 1) TABLESPACE  
REM  "USERS" LOGGING NOCOMPRESS ;
REM  ... 5 rows
把前面的REM去了,再去掉最后一行。创建表的DDL就做好了。

二、GET_DDL的例子:
set pagesize 0
set long 90000
set feedback off
set echo off  
spool get_allddl.sql  
connect    USERNAME/PASSWORD@SID;
SELECT DBMS_METADATA.GET_DDL('TABLE',u.table_name)
FROM USER_TABLES u;
SELECT DBMS_METADATA.GET_DDL('INDEX',u.index_name)
FROM USER_INDEXES u;
spool off;


三、脚本例子
set arraysize 1
set echo off
set heading off
set feedback off
set verify off
set pagesize 0
set linesize 79
define 1 = &&SCHEMA_NAME
spool tbl_&&SCHEMA_NAME
set termout off
col x noprint
col y noprint
select  'rem   ****    Create Table DDL for '||chr(10)||
        'rem   ****    '||username||''''||'s tables'||chr(10)||chr(10)
from    dba_users
where     username      = upper ('&&1')
/
select  table_name y,
        0 x,
        'create table ' ||
        rtrim(table_name) ||
        '('
from    dba_tables
where     owner = upper('&&1')
union
select  tc.table_name y,
        column_id x,
        rtrim(decode(column_id,1,null,','))||
        rtrim(column_name)|| ' ' ||
        rtrim(data_type) ||
        rtrim(decode(data_type,'DATE',null,'LONG',null,
               'NUMBER',decode(to_char(data_precision),null,null,'('),
               '(')) ||
        rtrim(decode(data_type,
               'DATE',null,
               'CHAR',data_length,
               'VARCHAR2',data_length,
               'NUMBER',decode(to_char(data_precision),null,null,
                 to_char(data_precision) || ',' || to_char(data_scale)),
               'LONG',null,
               '******ERROR')) ||
        rtrim(decode(data_type,'DATE',null,'LONG',null,
               'NUMBER',decode(to_char(data_precision),null,null,')'),
               ')')) || ' ' ||
        rtrim(decode(nullable,'N','NOT NULL',null))
from    dba_tab_columns tc,
        dba_objects o
where   o.owner = tc.owner
and     o.object_name = tc.table_name
and     o.object_type = 'TABLE'
and     o.owner = upper('&&1')
union
select  table_name y,
        999999 x,
        ')'  || chr(10)
        ||' STORAGE('                           || chr(10)
        ||' INITIAL '    || initial_extent      || chr(10)
        ||' NEXT '       || next_extent         || chr(10)
        ||' MINEXTENTS ' || min_extents         || chr(10)
        ||' MAXEXTENTS ' || max_extents         || chr(10)
        ||' PCTINCREASE '|| pct_increase        || ')' ||chr(10)
        ||' INITRANS '   || ini_trans         || chr(10)
        ||' MAXTRANS '   || max_trans         || chr(10)
        ||' PCTFREE '    || pct_free          || chr(10)
        ||' PCTUSED '    || pct_used          || chr(10)
        ||' PARALLEL (DEGREE ' || DEGREE || ') ' || chr(10)
        ||' TABLESPACE ' || rtrim(tablespace_name) ||chr(10)
        ||'/'||chr(10)||chr(10)
from    dba_tables
where   owner = upper('&&1')
order by 1,2
/
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP