DBMS_METADATA.GET_DDL是Oracle获取对象DDL最直接方式,但需预设SET LONG、PAGESIZE等参数防截断,通过SET_TRANSFORM_PARAM禁用STORAGE/TABLESPACE等冗余项,并确保用户具备SELECT_CATALOG_ROLE权限及正确指定schema才能成功执行。
是
oracle
中获取对象定义(ddl)最直接的方式,但它不是“一查就出可用 sql”的黑盒函数——输出是否干净、是否含 storage/segment 等细节、能否跨 schema 查、是否报权限错误,全取决于会话设置和调用方式。
为什么
返回结果被截断或显示不全
默认 SQL*Plus 或 SQL Developer 的
和
设置极小,
返回的是
,不显式调整就会只显示前 80 字符或几行。
必须在执行前运行:
(建议 ≥2M,避免大表 DDL 被截)
:关闭分页头尾,否则每页插入换行和标题
:防止行末空格被补满,影响 spool 输出
和
:避免额外文本混入结果
如何过滤掉 storage、tablespace、segment 等物理属性
生产环境导出 DDL 做迁移或比对时,
、
、
这类参数往往干扰阅读,且在目标库可能不适用。
临时禁用 storage 属性:
同时去掉段属性:
还原默认行为:
注意:这些是会话级设置,新连接需重设;不设的话,
默认包含全部物理定义
支持哪些 object_type 及常见权限陷阱
不是所有对象类型都能无条件查,也不是所有用户都能查任意 schema 的对象。
oracle知识库
oracle知识库下载
下载
常用
包括:
、
、
、
、
、
、
、
、
、
、
查别人 schema 的对象(如
),当前用户需有
或
权限,否则报
查
或
类型时,第三个参数(schema)不能传 NULL,必须明确写用户名,例如:
(此时不填 schema 参数会报错)
查触发器时注意命名冲突:同名触发器可能存在于不同表上,必须指定 owner 和 trigger_name,且确保该 trigger 存在于
中可查
批量导出某 schema 下所有表的 DDL 怎么写才安全
直接拼
+
容易因权限、对象不存在或 CLOB 拼接失败中断,需加容错和格式控制。
不要用
直接套整个查询,先确保单条能跑通,再加循环
推荐分步:
(防行宽截断)、
(提升 CLOB 读取效率)
关键语句示例(仅查当前用户可访问的表):
真正批量执行建议改用 PL/SQL 块 +
写文件,避免 SQL*Plus 缓冲区溢出;若只是临时查看,优先用
人工挑几个验证
真正麻烦的从来不是语法,而是权限上下文、CLOB 渲染边界、以及那些默认开启却没人告诉你该关的 transform 参数——比如
开启后,主键/外键会拆成
形式,和建表语句分离,这在做结构一致性校验时容易漏判。
dbms_metadata.get_ddlSELECT DBMS_METADATA.GET_DDL(...)LONGPAGESIZEGET_DDLCLOBSET LONG 2000000SET PAGESIZE 0SET TRIMSPOOL ONSET FEEDBACK OFFSET ECHO OFFSTORAGEINITIALFREELISTSEXECUTE 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, 'DEFAULT')GET_DDLDBMS_METADATA.GET_DDLobject_type'TABLE''VIEW''PROCEDURE''FUNCTION''TRIGGER''INDEX''SEQUENCE''PACKAGE''USER''TABLESPACE''MATERIALIZED VIEW'SCOTT.EMPSELECT_CATALOG_ROLESELECT ANY DICTIONARYORA-31603: object "EMP" of type TABLE not found in schema "SCOTT"'USER''ROLE'SELECT DBMS_METADATA.GET_DDL('USER', 'SCOTT') FROM DUALDBA_TRIGGERSDBA_TABLESGET_DDLspoolSET LINESIZE 32767SET LONGCHUNKSIZE 1000000SELECT 'SELECT DBMS_METADATA.GET_DDL(''TABLE'', ''' || table_name || ''', ''' || owner || ''') FROM DUAL;'
FROM all_tables
WHERE owner = 'SCOTT';UTL_FILESELECT ... FROM DBA_OBJECTS WHERE OBJECT_TYPE = 'TABLE''CONSTRAINTS_AS_ALTER'ALTER TABLE ADD CONSTRAINT