必须配置set long 2000000、set pagesize 0、set trimspool on、set feedback off和set echo off防止clob截断与格式污染;对象名、类型名须全大写;跨schema需指定大写owner并授select_catalog_role权限;禁用storage/segment_attributes/tablespace等冗余项;package body须用'package'类型参数而非'package body'。

直接执行 DBMS_METADATA.GET_DDL 几乎必然失败或返回截断内容——不是函数有问题,而是你没配终端、没调参数、没校验大小写。
SQL*Plus 里执行前必须设的四个终端参数
不设这些,DBMS_METADATA.GET_DDL 返回的 CLOB 会被默认截成 80 字符,还混入页眉、换行和“1 row selected”这类干扰行。
-
SET LONG 2000000:必须 ≥2M,大表或带注释的包体常超 10 万字节 -
SET PAGESIZE 0:关掉分页头尾,否则每页夹杂------和列名 -
SET TRIMSPOOL ON:防止SPOOL输出时补空格,破坏CREATE TABLE语句结构 -
SET FEEDBACK OFF和SET ECHO OFF:避免“已选择 1 行”污染结果
查不到对象就报 ORA-31603?先核对这三个大小写细节
Oracle 数据字典里所有对象名、类型名、owner 名都是大写的。小写或引号不匹配,函数就静默返回空或直接报错。
- 对象名必须大写:
GET_DDL('TABLE', 'EMP')可行,'emp'或'Emp'都不行 - 对象类型名必须全大写且准确:
'PROCEDURE'、'PACKAGE'、'REF_CONSTRAINT'—— 写成'procedure'或'PK'就失败 - 带双引号创建的对象(如
CREATE TABLE "MyTable")必须传'"MyTable"',否则 Oracle 默认按'MYTABLE'查,找不到
导出 DDL 带 STORAGE/TABLESPACE/SEGMENT_ATTRIBUTES 怎么办
这些物理属性在迁移或逻辑比对时毫无价值,反而导致目标库执行失败(比如表空间不存在)。禁用它们不是可选项,是必做动作。
- 执行
EXEC DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE', FALSE) - 同理禁用段属性:
EXEC DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_ATTRIBUTES', FALSE) - 禁用表空间:
EXEC DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'TABLESPACE', FALSE) - 想提升可读性,加格式化:
EXEC DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'PRETTY', TRUE)
注意:这些是会话级设置,新开 SQL*Plus 连接或重连后必须重设;漏设一次,输出就带 STORAGE (INITIAL 65536)。
为什么 PACKAGE BODY 总是返回空
DBMS_METADATA.GET_DDL 对 'PACKAGE BODY' 类型不支持——它不报错,但返回空 CLOB。这是文档没明说、但实际存在的硬限制。
- 查包体必须用
GET_DDL('PACKAGE', 'PKG_NAME', 'OWNER'),它会同时返回包头 + 包体定义 - 单独查
'PACKAGE BODY'永远为空,别浪费时间排查权限或拼写 - 同理,
'TYPE BODY'也不支持,得用'TYPE'类型参数
真正容易被忽略的是:这个限制没有错误提示,你只会看到一片空白,然后反复检查 owner 名是否大写、权限是否够——其实问题根本不在那儿。











