以自动化方式编写 Oracle DDL 脚本

Mat*_*day 14 oracle export scripting oracle-sql-developer ddl

Oracle SQL Developer 能够通过Tools -> Database Export...这种方式导出 DDL效果很好,但需要人工干预。

我知道DBMS_METADATA.get_ddl(),但发现导出并不完美。我遇到了导出的DBMS_METADATADDL 无法使用的问题,如果没有首先解决诸如关键字中间中断之类的问题,甚至更糟。但是,如果有人知道一种DMBS_METADATA无需手动修复即可运行的导出 DDL 的方法,那也将是一个很好的解决方案。

基本上,我正在寻找一种自动/脚本化的方式来导出通过手动方式导出的 DDL相同的DDL 。

我怎样才能做到这一点?

Nic*_*mas 6

您遇到问题的原因dbms_metadata.get_ddl是它输出的CLOBs 大小可达 4GB。默认情况下,SQL*Plus 和 Oracle SQL Developer 会截断长文本,这样它们就不会用大量文本破坏客户端。

在 SQL*Plus 中使用一些SET命令覆盖这种行为并获得干净的 DDL非常容易。

你需要的脚本是:

-- Run this script in SQL*Plus.

-- don't print headers or other crap
set heading off;
set echo off;
set pagesize 0;      

-- don't truncate the line output
-- trim the extra space from linesize when spooling
set long 99999;      
set linesize 32767;  
set trimspool on;    

-- don't truncate this specific column's output
col object_ddl format A32000;

spool sys_ddl.sql;

SELECT dbms_metadata.get_ddl(object_type, object_name, owner) || ';' AS object_ddl
FROM DBA_OBJECTS
WHERE 
      OWNER = 'SYS'
  AND OBJECT_TYPE IN (
      'TABLE'
    , 'INDEX'
    , 'SEQUENCE'
    , 'VIEW'
  )
ORDER BY
    OWNER
  , OBJECT_TYPE
  , OBJECT_NAME
;

spool off;
Run Code Online (Sandbox Code Playgroud)


小智 5

好吧,如果 sqlplus 搞砸了您的 dbms_metadata.get_ddl 输出,为什么不在 CLOB 中选择输出并将 CLOB 写入文件系统。

例如

DECLARE
    data CLOB;
    objType varchar2(30) := 'TABLE';
    objSchema varchar2(30) := 'SCOTT';
    objName varchar2(30) := 'EMP';
    fname varchar2(256) := objType || '_' || objSchema || '_' || objName || '.sql';
BEGIN
    SELECT dbms_metadata.get_ddl(objType,objName,objSchema) into data from dual;
    DBMS_XSLPROCESSOR.CLOB2FILE(data,'DATA_PUMP_DIR',fname);
END;
/
Run Code Online (Sandbox Code Playgroud)

这应该会让你得到正确的 DDL,没有输出混乱。唯一的问题是脚本将在数据库服务器上创建,而不是在您调用 sqlplus 的客户端上创建。

该脚本保存在 DB 服务器上的“DATA_PUPM_DIR”条目指向的目录中。IE

select directory_path from all_directories where directory_name like 'DATA_PUMP_DIR';
Run Code Online (Sandbox Code Playgroud)

更重要的是,您可以在模式的所有表/索引等上添加某种迭代,并立即获得完整模式的 DDL。我总是这样做。

  • 请注意,这会将文件写入服务器的文件系统。任何希望在客户端计算机上获取 DDL 的人都无法实现。 (2认同)