使用dbms_metadata.get_ddl需先执行set long 2000000、set pagesize 0、set trimspool on、set feedback off等终端配置,否则clob返回值会被截断或格式混乱;还需调用set_transform_param禁用storage、segment_attributes等冗余项并启用pretty格式化。
直接用 dbms_metadata.get_ddl 能查,但不设参数、不调终端配置,90% 情况下你看到的只是半截 sql 或一堆乱码。
为什么 SELECT DBMS_METADATA.GET_DDL(...) 返回结果被截断或格式混乱
因为 GET_DDL 返回的是 CLOB,而 SQL*Plus / SQL Developer 默认的 LONG 值通常只有 80 字符,PAGESIZE 会插入页眉页脚,FEEDBACK 还会加“1 row selected”这类干扰行。
- 必须提前执行:
SET LONG 2000000(建议 ≥2M,大表 DDL 动辄上万字符) -
SET PAGESIZE 0:关闭分页,否则每页夹杂换行和标题 -
SET TRIMSPOOL ON:防止 spool 输出时补空格破坏语句结构 -
SET FEEDBACK OFF和SET ECHO OFF:避免额外文本混入结果 - 如果用 SQL Developer,还要在【Preferences → Database → Worksheet】里勾选 “Treat script as one statement” 并调高 “SQL Array Fetch Size”
怎么去掉 STORAGE、TABLESPACE、SEGMENT_ATTRIBUTES 等冗余项
默认输出包含物理存储细节,迁移或比对时不仅干扰阅读,还可能在目标库报错(比如表空间不存在)。
- 禁用 storage 参数:
EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE', FALSE) - 禁用段属性(如
SEGMENT CREATION IMMEDIATE):EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_ATTRIBUTES', FALSE) - 启用格式化换行(提升可读性):
EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'PRETTY', TRUE) - 还原默认行为(查完记得清):
EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'DEFAULT')
这些是会话级设置,新开连接必须重设;没设就调 GET_DDL,输出一定带 storage。
查别人 schema 的对象或特殊类型(如 USER、OBJECT_GRANT)要注意什么
权限和参数写错,不是返回空,而是直接报错,比如 ORA-31603 或 ORA-19206。
- 查非当前用户对象(如
SCOTT.EMP),当前用户必须有SELECT_CATALOG_ROLE或SELECT ANY DICTIONARY权限 - 查
'USER'类型时,第三个参数(schema)不能为NULL,必须写成SELECT DBMS_METADATA.GET_DDL('USER', 'SCOTT') FROM DUAL(注意用户名大写) - 查对象权限用
DBMS_METADATA.GET_GRANTED_DDL('OBJECT_GRANT', 'SCOTT'),它自动合并表级和列级授权,但不解析同义词 —— 如果授权目标是同义词,生成的语句仍按同义词名输出,执行时可能报ORA-00942 - 系统权限、角色权限、默认角色要分开查:
SYSTEM_GRANT、ROLE_GRANT、DEFAULT_ROLE,漏一个,克隆用户就可能无法登录
常见 object_type 列表和容易忽略的细节
GET_DDL 支持的类型远不止 'TABLE' 和 'INDEX',但部分类型调用方式不同,且大小写敏感。
- 常用类型:
'TABLE'、'VIEW'、'PROCEDURE'、'FUNCTION'、'TRIGGER'、'INDEX'、'SEQUENCE'、'PACKAGE'、'MATERIALIZED VIEW'、'TABLESPACE'、'USER' -
'TABLESPACE'调用时不传 schema 参数,例如:SELECT DBMS_METADATA.GET_DDL('TABLESPACE', 'USERS') FROM DUAL - 所有对象名、schema 名都需大写(除非建对象时用了双引号定义小写名)
- 函数第四个参数(
version)极少用,但若显式传TRUE(如GET_DDL('TABLE', 'T', 'U', TRUE)),会强制包含完整存储定义,与前面禁用STORAGE的设置冲突 —— 不建议混用
最常被跳过的其实是权限组合:只导了 OBJECT_GRANT,却忘了 SYSTEM_GRANT 和 DEFAULT_ROLE,结果重建用户后连 CREATE SESSION 都没有。











