DBMS_METADATA.GET_DDL('PROCEDURE', ...) 返回完整可执行的CREATE OR REPLACE PROCEDURE语句,但需设置SET LONG 100000、对象名大写、跨schema显式指定owner;包内过程须用'PACKAGE BODY'类型查询,不可用点号传参。

直接用 DBMS_METADATA.GET_DDL 就能拿到可执行的完整建过程语句,但默认会截断、大小写敏感、不自动处理包体——这些细节不调好,查出来就是半截代码或报错。
DBMS_METADATA.GET_DDL('PROCEDURE', ...) 返回的是 DDL,不是源码文本
它输出的是 CREATE OR REPLACE PROCEDURE ... 开头的完整建对象语句,含函数体、异常块、注释、权限授予等,比 USER_SOURCE 拼接更可靠。但注意:
- 返回类型是
CLOB,在 SQL*Plus 或 SQL Developer 中默认只显示前 4000 字符,必须提前运行SET LONG 100000(或更大) - 如果过程名含小写或带双引号(如
"my_proc"),GET_DDL会查不到——Oracle 内部统一存大写,传参时必须用大写名 - 它自动识别当前用户 schema,无需填 owner;但若查别人的过程,第三个参数得显式指定 schema 名,例如
DBMS_METADATA.GET_DDL('PROCEDURE', 'MY_PROC', 'SCOTT')
包里的过程不能用 PROCEDURE 类型直接查
如果过程定义在包体内(比如 pkg_name.my_proc),GET_DDL('PROCEDURE', 'MY_PROC') 查不到——因为 Oracle 把它归类为 PACKAGE BODY 的一部分,不是独立 PROCEDURE 对象。
- 要查整个包体,用
DBMS_METADATA.GET_DDL('PACKAGE BODY', 'PKG_NAME'),结果里自然包含所有过程和函数的实现 - 想单独定位某个过程在包体中的位置?先用
USER_SOURCE查包体源码:SELECT text FROM USER_SOURCE WHERE name = 'PKG_NAME' AND type = 'PACKAGE BODY' ORDER BY line - 别误用
GET_DDL('PROCEDURE', 'PKG_NAME.MY_PROC')——语法合法但查无结果,Oracle 不支持点号分隔的对象名传参
ORA-22835 错误:CLOB 转 CHAR 失败
常见于把 GET_DDL 结果套进 TO_CHAR() 或拼接字符串时,比如导出脚本写成:SELECT TO_CHAR(DBMS_METADATA.GET_DDL(...)) FROM DUAL。
- 根本原因:CLOB 超过 4000 字节,
TO_CHAR强制转 CHAR 触发截断报错 - 正确做法:去掉
TO_CHAR,直接 SELECT CLOB;或改用DBMS_LOB.SUBSTR分段读取(不推荐,易丢内容) - 批量导出时,SQL*Plus 中加
SET LONGCHUNKSIZE 100000配合SET LONG,避免 spool 文件被截断
真正难的不是调哪个函数,而是理解 Oracle 怎么组织对象:独立过程、包头、包体是三类不同对象,GET_DDL 的 object_type 必须严格匹配,大小写、schema、是否加密、编译状态都会影响结果——漏掉任一条件,就只能看到空行或 ORA 错误。


















