简答题 16.  如何导出存储过程、函数、包和触发器的定义语句?如何导出表的结构?如何导出索引的创建语句?
【正确答案】总体来说有两种方式来获取,第一,利用系统包DBMS_METADATA包中的GET_DDL函数来获取,第二,利用exp或expdp来获取。
   下面来看第一种方式,如何利用系统包DBMS_METADATA包中的GET_DDL函数来获取对象的定义语句。下面是该函数的入参和出参:
   
   其详细参数如下:
   (1)OBJECT_TYPE:需要返回原数据的DDL语句的对象类型。
   (2)NAME:对象名称。
   (3)SCHEMA:对象所在的SCHEMA,默认为当前用户所在SCHEMA。
   (4)VERSION:对象原数据的版本。
   (5)MODEL:原数据的类型默认为ORACLE。
   (6)TRANSFORM:默认值为DDL。
   (7)RETURNS:对象的原数据默认以CLOB类型返回。
   一般情况下,只需要给出OBJECT_TYPE、NAME和SCHEMA 3个参数即可。
   1)查看创建表SQL语句:
   
   2)查看创建索引的SQL语句:
   
   3)查看创建主键的SQL语句:
   
   4)查看创建外键的SQL语句:
   
   5)查看创建视图(VIEW)的SQL语句:
   
   6)查看创建存储过程(PROCEDURE)的SQL语句:
   
   7)查看创建触发器(TRIGGER)的SQL语句:
   
   8)查看创建函数(FUNCTION)的SQL语句:
   
   9)查看创建包(PACKAGE)的SQL语句:
   
   10)查看创建序列(SEQUENCE)的SQL语句:
   
   11)查看创建同义词(SYNONYM)的SQL语句:
   
   12)查看创建表空间(TABLESPACE)的SQL语句:
   
   13)查看创建角色(ROLE)的SQL语句:
   
   14)查看创建用户(USER)的SQL语句:
   
   15)得到一个用户下的所有表、索引、存储过程、函数的DDL语句:
   
   若想去掉表的存储参数(例如,INITIAL、NEXT、FREELISTS等参数),则可以使用DBMS METADATA包中的函数SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE',FALSE)来完成。
   使用DBMS_METADATA.GET_DDL需要注意以下问题:
   1) DBMS_METADATA.GET_DDL()包内的参数都要大写,否则会报出ORA-31600: invalid input value table for parameter OBJECT_TYPE in function GET_DDL的错误。
   2)是否查的当前用户的DDL语句,若不是则需要加上对象的属主信息,即SCHEMA参数。
   3)若在SQL*Plus中显示不全,则需要set long 9999。
   现在来回答本题目中的问题,代码如下:
   
   
   下面介绍第二种导出元数据的方法,就是采用exp或expdp命令。数据泵工具(impdp)提供了SQLFILE的命令行选项,只获取DDL语句,并未真正地执行数据导入。另外,若单纯为了导出DDL语句则司‘以在使用expdp导出的时候使用CONTENT=METADATA_ONLY和EXCLUDE=STATISTICS选项,这样导出的DMP文件比较小。如下:
   
   查看expddl_lhr.sql文件即可获取DDL语句。
   imp工具使用SHOW=Y LOG=GET_DDL.sql的方式,可以看到清晰的DDL脚本,同时也不会真正地执行数据导入。另外,若单纯为了导出DDL语句则可以在使用exp导出的时候使用ROWS=N选项,这样导出的DMP文件比较小。如下:
   
   查看get_ddl.sql文件即可获取DDL语句。不过对于exp生成的DDL语句不能直接使用,需要使用SHELL脚本(脚本参考随书提供的pdf文档)做相应的处理后才能使用。另外,使用imp工具的indexfle选项也可以把dmp文件中的表和索引的创建语句导出而不导入任何对象,命令如下:
   
【答案解析】