Oracle专家必须频繁地从Oracle里提取出表格或者索引的定义,并将它们移植到不同的系统里。从字典里提取出用于Oracle结构描述对象(例如,表格、索引、存储过程、触发器、顺序等等)的数据定义语言(Data Definition Language,DDL),在你将系统移植到新的平台上,以及当你想要在tablespace里预先创建对象的时候很有用。
一般来说,在Oracle的移植里,结构描述和DDL都是在目标数据库里创建的,然后使用Oracle里带有IGNORE=Y参数的imp工具将数据列导入到新的数据库里。IGNORE=Y这个参数会告诉Oracle要使新的DDL定义,而不是使用导入数据文件里的DDL。
在Oracle9i之前,获取表格和索引的DDL是一个既费时又麻烦的过程。你可以运行带有ROWS=NO参数的导出工具——exp,但是其输出却由于每一行的引用字符串以及不佳的格式而很难重复使用。其他唯一的选择就是编写复杂的字典脚本(dictionary script),但是这些脚本可能无法对诸如IOT和嵌套表格这样的复杂对象使用。
但是在Oracle9i里,你可以使用一个叫做dbms_metadata的新的工具包,它能够轻易地直接显示数据字典里的DDL和存储过程。使用这个强大的工具,你就可以提取出独立的对象或者整个Oracle的结构描述。最好的消息是,它很容易使用。你只用简单地执行 dbms_metadata.get_ddl,并指定对象名,Oracle就会提取出马上能够使用的DDL。
要提取出整个表格以及用于EMP表格的索引,就要执行dbms_metadata. get_ddl,从DUAL里进行选择,再提供所有必需的参数,如Listing A所示。
set heading off;
set echo off;
Set pages 999;
set long 90000;
spool ddl_list.sql
select dbms_metadata.get_ddl('TABLE','DEPT','SCOTT') from dual;
select dbms_metadata.get_ddl('INDEX','DEPT_IDX','SCOTT') from dual;
spool off;
其输出如Listing B所示。唯一却失的东西就是每个陈述式之后的结束分号(;)。为了说明问题,我将演示如何使用INDEX自变量将主要关键字作为表格DDL的一部分提取出来,或者单独提取出来。
CREATE TABLE "SCOTT"."DEPT"
( "DEPTNO" NUMBER(2,0),
"DNAME" VARCHAR2(14),
"LOC" VARCHAR2(13),
CONSTRAINT "PK_DEPT" PRIMARY KEY ("DEPTNO")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 12288 NEXT 12288 MINEXTENTS 1 MAXEXTENTS 249 PCTINCREASE 50
FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) TABLESPACE "SYSTEM" ENABLE
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 LOGGING
STORAGE(INITIAL 12288 NEXT 12288 MINEXTENTS 1 MAXEXTENTS 249 PCTINCREASE 50
FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) TABLESPACE "SYSTEM"
CREATE UNIQUE INDEX "SCOTT"."DEPT_IDX" ON "SCOTT"."DEPT" ("DNAME")
; FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) TABLESPACE "SYSTEM"
要注意,你已经完成了表格和索引的定义,包括存储参数(例如,pctfree、pctused、freelists和freelist groups),以及tablespace存储和缓冲池指令(buffer pool directive)。
对于大范围的迁移,你可以修改dbms_metadata句法来提取出整个结构描述。正如你可以在Listing C里看到的,选择dbms_metadata. get_ddl并指定USER_TABLES和USER_INDEXES就能够轻易实现这一点。这个句法会提取出用于整个结构描述(在本例里,就是scott结构描述)的完整表格和索引定义。
set pagesize 0
set long 90000
set feedback off
set echo off
spool scott_schema.sql
connect scott/tiger;
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;
