跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

Oracle PL/SQL中怎么获取对象定义_使用DBMS_METADATA查询

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

相关文章