查user类型ddl必须显式指定大写schema参数,不可为null或省略,否则报ora-31603或ora-19206;需授予select_catalog_role权限,并配置set long 2000000、禁用storage/segment_attributes等参数防截断和冗余。

查 USER 类型必须显式传 schema 参数
查用户 DDL 时,DBMS_METADATA.GET_DDL 的第三个参数 schema 不能为 NULL 或省略,否则直接报错 ORA-31603 或 ORA-19206。即使查当前用户自己,也得写成用户名本身:
-
SELECT DBMS_METADATA.GET_DDL('USER', 'SCOTT') FROM DUAL;✅ 正确(注意用户名大写) -
SELECT DBMS_METADATA.GET_DDL('USER', 'scott') FROM DUAL;❌ 报ORA-31603(数据字典里存的是大写) -
SELECT DBMS_METADATA.GET_DDL('USER', 'SCOTT', NULL) FROM DUAL;❌ 报ORA-19206(USER 类型不接受 NULL schema)
权限不足会直接失败,不是返回空
执行 GET_DDL('USER', ...) 要求当前用户有 SELECT_CATALOG_ROLE 或 SELECT ANY DICTIONARY 权限。没权限时不会静默跳过,而是明确报错:
-
ORA-31600: invalid input value for parameter SCHEMA—— 实际是权限拒绝的伪装错误 -
ORA-01031: insufficient privileges—— 更直白的提示(取决于 Oracle 版本)
验证权限可用:SELECT * FROM SESSION_ROLES WHERE ROLE IN ('SELECT_CATALOG_ROLE', 'SELECT ANY DICTIONARY');
必须禁用 STORAGE 和 SEGMENT_ATTRIBUTES
默认输出含 DEFAULT TABLESPACE、TEMPORARY TABLESPACE、PROFILE 等物理属性,但这些在目标库很可能不存在或不适用。关键设置如下:
EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE', FALSE);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);(提升可读性)
这些是会话级设置,新开 SQL*Plus / SQL Developer 连接后需重设。
终端配置不到位,DDL 一定被截断
GET_DDL 返回 CLOB,而 SQL*Plus 默认 LONG 是 80 字符。不调参的结果是:只看到 CREATE USER "SCOTT" IDENTIFIED BY VALUES ' 就断了。
-
SET LONG 2000000—— 建议 ≥2M,用户 DDL 含密码哈希、角色授权等,常超 10K 字符 -
SET PAGESIZE 0—— 关闭页眉页脚,避免混入---------或列名 -
SET TRIMSPOOL ON—— 防止 spool 输出时右侧补空格破坏语句结构 -
SET FEEDBACK OFF和SET ECHO OFF—— 屏蔽1 row selected等干扰行
SQL Developer 用户还需在 Preferences → Database → Worksheet 中勾选 Treat script as one statement 并调高 SQL Array Fetch Size,否则仍可能分段返回。
最易被忽略的是:SET_TRANSFORM_PARAM 设置不还原,会影响后续所有 GET_DDL 调用;而 SET LONG 等终端参数一旦漏设,你拿到的就不是“不完整”,而是“根本不可用”的半截语句。











