在9i以前,没有什么太好的方法,一般是通过查询数据字典,然后自己根据语法来拼接成一个完整的DDL语句,缺点是十分麻烦,需要用户对DDL的语法十分熟悉,而且经常容易缺失一些关键字。最重要的是,查询表的DDL与查询视图的DDL的方法就完全不一样,要获取多种对象的DDL,就需要为每种DDL来单独构造一个SQL。
此外,还有一种方法,就是利用Oracle的EXP工具。在导入的时候指定INDEXFILE,使得导入工具将DDL写入到一个文件中。这种方法的好处是不需要用户自己来拼接DDL了,而且支持多种类型的DDL,缺点也很明显,得到的结果无法直接使用,需要手工进行编辑,而编辑过程本身就很麻烦,会消耗大量的时间。
从9i开始,这个问题变得很轻松了,只需要一个查询语句,就可以获取对象的详细的DDL描述,上面所有的缺点完全被客服了:
SQL> SELECT DBMS_METADATA.GET_DDL('TABLE', 'OZ_MEMBER') FROM DUAL;
除了这个最常用的方法之外,利用DBMS_METADATA.OPEN的方式也可以达到相同的效果:
SET SERVEROUT ON SIZE 100000;
DECLARE
V_STR CLOB;
V_HANDLE NUMBER;
V_TRANS_HANDLE NUMBER;
BEGIN
V_HANDLE := DBMS_METADATA.OPEN('TABLE');
DBMS_METADATA.SET_FILTER(V_HANDLE, 'NAME', 'OZ_MEMBER', 'TABLE');
V_TRANS_HANDLE := DBMS_METADATA.ADD_TRANSFORM(V_HANDLE, 'DDL');
V_STR := DBMS_METADATA.FETCH_CLOB(V_HANDLE);
FOR I IN 1..CEIL(DBMS_LOB.GETLENGTH(V_STR)/200) LOOP
DBMS_OUTPUT.PUT_LINE(DBMS_LOB.SUBSTR(V_STR, 200, (I-1)*200 + 1));
END LOOP;
END;
/
后面这个方法虽然麻烦一些,但是功能很强,可以设置过滤、转换等功能,这在随后的文章中会进一步描述。