使用DBMS_METADATA.GET_DDL获取对象的DDL脚本

--GET_DDL:       Return the metadata for a single object as DDL.

-- This interface is meant for casual browsing (e.g., from SQLPlus)

-- vs. the programmatic OPEN / FETCH / CLOSE interfaces above.

-- 参数  :

-- object_type - The type of object to be retrieved.

-- name - Name of the object.  表名或索引名, procedure名 等等   

-- schema - Schema containing the object. Defaults to

-- the caller's schema.

-- version - The version of the objects' metadata.

-- model - The object model for the metadata.

-- transform. - XSL-T transform. to be applied.

-- RETURNS: Metadata for the object transformed to DDL as a CLOB.

 

FUNCTION get_ddl ( object_type IN VARCHAR2,

name IN VARCHAR2,

schema IN VARCHAR2 DEFAULT NULL,

version IN VARCHAR2 DEFAULT 'COMPATIBLE',

model IN VARCHAR2 DEFAULT 'ORACLE',

transform. IN VARCHAR2 DEFAULT 'DDL') RETURN CLOB;

 

1.得到一个表或索引的ddl语句

SELECT DBMS_METADATA.GET_DDL('TABLE','DEPT','SCOTT') FROM DUAL;

select dbms_metadata.get_ddl('INDEX','PK_DEPT','SCOTT') from dual;

2.得到一个用户下的所有表,索引,存储过程的ddl

SELECT DBMS_METADATA.GET_DDL(U.OBJECT_TYPE, u.object_name)
FROM USER_OBJECTS u
where U.OBJECT_TYPE IN ('TABLE','INDEX','PROCEDURE');

3.得到所有表空间的ddl语句

SELECT DBMS_METADATA.GET_DDL('TABLESPACE', TS.tablespace_name)
FROM DBA_TABLESPACES TS;

4.得到所有创建用户的ddl

SELECT DBMS_METADATA.GET_DDL('USER',U.username)
FROM DBA_USERS U;

================================================================================

9i  中可以利用DBMS_METADATA.GET_DDL包得到数据库的对象的ddl脚本。如下(SQLPLUS中执行):

a. 获取单个的建表、视图和建索引的语法

set pagesize 0
set long 90000
set feedback off
set echo off
spool DEPT.sql
select dbms_metadata.get_ddl('TABLE','TAB_NAME','SCOTT') from dual;
select dbms_metadata.get_ddl('VIEW','VIEW_NAME','SCOTT') from dual;
select dbms_metadata.get_ddl('INDEX','IDX_NAME','SCOTT') from dual;
spool off;
  
b.获取一个SCHEMA下的所有建表、视图和建索引的语法,以scott为例:
 
set pagesize 0
set long 90000
set feedback off
set echo off
spool schema.sql
connect scott/tiger;
SELECT DBMS_METADATA.GET_DDL('TABLE',u.table_name) FROM USER_TABLES u;
 SELECT DBMS_METADATA.GET_DDL('VIEW',u.VIEW_name) FROM USER_VIEWS u;
SELECT DBMS_METADATA.GET_DDL('INDEX',u.index_name) FROM USER_INDEXES u;
spool off;

c.    获取某个SCHEMA的建全部存储过程的语法
 
set pagesize 0
set long 90000
set feedback off
set echo off
spool procedures.sql 
select   DBMS_METADATA.GET_DDL('PROCEDURE',u.object_name) from     user_objects u where     object_type = 'PROCEDURE';
spool off;

d.    获取某个SCHEMA的建全部函数的语法
 
set pagesize 0
set long 90000
set feedback off
set echo off
spool function.sql 
select   DBMS_METADATA.GET_DDL('FUNCTION',u.object_name) from     user_objects u where     object_type = 'FUNCTION';
spool off;  

------------------------------------------------

 

例子 : 

 

SQL> set pagesize 0
SQL> set long 90000
SQL> set feedback off
SQL> set echo off
SQL> spool   schema.sql
SQL>
SQL> select dbms_metadata.get_ddl('TABLE','EDIBTO850_PO1PID','DFMS') from dual;  

SQL>  spool off;
  CREATE TABLE "DFMS"."EDIBTO850_PO1PID"
   (    "CONTROLNUMBER" VARCHAR2(40) NOT NULL ENABLE,
        "BEG03" VARCHAR2(20) NOT NULL ENABLE,
        "PO101" VARCHAR2(20) NOT NULL ENABLE,
        "SEQNO" NUMBER(*,0) NOT NULL ENABLE,
        "PO109" VARCHAR2(20) DEFAULT (''),
        "PID01" CHAR(1) DEFAULT (''),
        "PID02" VARCHAR2(3) DEFAULT (''),
        "PID05" VARCHAR2(200) DEFAULT ('') NOT NULL ENABLE,
        "PID08" CHAR(1) DEFAULT (''),
        "LASTEDITDT" DATE DEFAULT (sysdate),
        "CREATE_TIME" DATE DEFAULT sysdate,
        "TIEGROUP" VARCHAR2(35),
         CONSTRAINT "EDIBTO850_PO1PID_PK" PRIMARY KEY ("CONTROLNUMBER", "BEG03", "PO101
", "SEQNO", "PID05")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 104857600 NEXT 104857600 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DE
FAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SN_IDX"  ENABLE
   ) PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 NOCOMPRESS  LOGGING
  STORAGE(
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "PART_D_TS2"
  PARTITION BY RANGE ("CREATE_TIME")
 (PARTITION "P200907"  VALUES LESS THAN (TO_DATE(' 2009-07-01 00:00:00', 'SYYYY-
MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 52428800 NEXT 52428800 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DE
FAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "PART_D_TS2" ,
 PARTITION "P201001"  VALUES LESS THAN (TO_DATE(' 2010-01-01 00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 52428800 NEXT 52428800 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DE
FAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "PART_D_TS2" ,
 PARTITION "P201007"  VALUES LESS THAN (TO_DATE(' 2010-07-01 00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 52428800 NEXT 52428800 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DE
FAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "PART_D_TS2" ,
 PARTITION "P201101"  VALUES LESS THAN (TO_DATE(' 2011-01-01 00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 52428800 NEXT 52428800 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DE
FAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "PART_D_TS2" ,
 PARTITION "P201107"  VALUES LESS THAN (TO_DATE(' 2011-07-01 00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 52428800 NEXT 52428800 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DE
FAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "PART_D_TS2" ,
 PARTITION "P201201"  VALUES LESS THAN (TO_DATE(' 2012-01-01 00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 52428800 NEXT 52428800 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DE
FAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "PART_D_TS2" ,
 PARTITION "P201207"  VALUES LESS THAN (TO_DATE(' 2012-07-01 00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 52428800 NEXT 52428800 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DE
FAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "PART_D_TS2" ,
 PARTITION "P201301"  VALUES LESS THAN (TO_DATE(' 2013-01-01 00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 52428800 NEXT 52428800 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DE
FAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "PART_D_TS2" ,
 PARTITION "P201307"  VALUES LESS THAN (TO_DATE(' 2013-07-01 00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 52428800 NEXT 52428800 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DE
FAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "PART_D_TS2" ,
 PARTITION "P201401"  VALUES LESS THAN (TO_DATE(' 2014-01-01 00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 52428800 NEXT 52428800 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DE
FAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "PART_D_TS2" ,
 PARTITION "P201407"  VALUES LESS THAN (TO_DATE(' 2014-07-01 00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 52428800 NEXT 52428800 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DE
FAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "PART_D_TS2" ,
 PARTITION "P201501"  VALUES LESS THAN (TO_DATE(' 2015-01-01 00:00:00', 'SYYYY-M
M-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 52428800 NEXT 52428800 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DE
FAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "PART_D_TS2" ,
 PARTITION "PMAX"  VALUES LESS THAN (MAXVALUE) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 52428800 NEXT 52428800 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DE
FAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "PART_D_TS2" )  ENABLE ROW MOVEMENT

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/35489/viewspace-713348/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/35489/viewspace-713348/

<think>好的,用户在使用Oracle的DBMS_METADATA.GET_DDL时遇到了SQL被截断的问题,我需要帮他解决这个问题。首先,我得回忆一下DBMS_METADATA.GET_DDL的输出机制。这个函数返回的是CLOB类型的数据,CLOB可以存储大量的字符数据,但不同的客户端工具处理CLOB的方式可能不同,特别是像SQL*Plus这样的命令行工具可能会有默认的显示限制。 用户提到输出被截断,这可能是因为客户端设置的显示长度不够。例如,SQL*Plus中的LONG参数默认是80个字符,这会导致较长的DDL语句显示不全。所以解决方法可能是调整这些参数,比如设置SET LONG 100000或者更大的值,同时设置PAGESIZE为0,避免分页打断输出。 另外,用户可能是在使用其他工具,比如PL/SQL Developer或SQL Developer,这些工具可能也有自己的显示设置,需要检查是否有类似的限制。如果用户使用的是SQL Developer,可能需要调整显示的选项,或者在导出时直接保存到文件,避免在界面中显示不全。 还有一种可能是用户没有正确获取完整的DDL,比如没有处理转换参数,导致部分存储参数被省略。这时候可能需要使用DBMS_METADATA.SET_TRANSFORM_PARAM来调整输出格式,比如禁用STORAGE参数,或者启用更详细的转换选项。 另外,用户可能需要生成多个相关对象DDL,比如索引、约束等,这时候可能需要使用ADD_TRANSFORM函数来包含这些对象。但用户的问题主要在于截断,所以重点应该放在客户端设置上。 我还需要确认用户是否在查询时正确使用了函数,比如是否遗漏了schema参数,或者表名是否正确大写,因为Oracle的数据字典是区分大小写的,如果表名没有正确大写,可能导致查询不到结果,但用户的问题是关于截断,所以可能不是这个原因。 最后,可能需要建议用户将结果输出到文件,避免客户端的显示限制,或者使用其他工具如TOAD,这些工具可能自动处理CLOB的显示问题。同时,提醒用户检查是否有权限问题,但之前的回答已经提到过权限,这里可能不是主要原因。 总结一下,用户的问题可能出在客户端工具的显示设置,特别是LONG和PAGESIZE的设置,需要指导用户调整这些参数,或者将结果保存到文件中,确保完整输出。同时,可以提到使用其他方法如SQL Developer导出DDL,避免截断问题。</think>在Oracle中使用 `DBMS_METADATA.GET_DDL` 时出现SQL截断问题,通常是由于客户端工具的默认显示限制导致的。以下是详细解决方案: --- ### **问题原因** 1. **CLOB字段显示限制** `DBMS_METADATA.GET_DDL` 返回的数据类型是 `CLOB`,而SQL*Plus等工具的默认设置(如 `LONG` 参数)会限制大文本的显示长度。 2. **工具缓冲区限制** 部分数据库工具(如PL/SQL Developer)的查询结果窗口有默认的字符长度限制。 --- ### **解决方案** #### **方法1:调整SQL*Plus设置** 在命令行工具中执行以下命令: ```sql SET LONG 1000000 -- 设置CLOB显示长度(默认80) SET LONGCHUNKSIZE 1000000 -- 设置分段读取长度 SET PAGESIZE 0 -- 禁用分页显示 SET LINESIZE 32767 -- 设置单行最大宽度(可选) ``` **执行示例**: ```sql SQL> SET LONG 1000000 SQL> SELECT DBMS_METADATA.GET_DDL('TABLE', 'EMP') FROM DUAL; ``` --- #### **方法2:通过TOAD/SQL Developer导出** - **在SQL Developer中**: 1. 执行查询后,右键点击结果网格中的 `CLOB` 字段 2. 选择 **Export Single Cell...** 3. 将完整DDL保存到文件 - **在TOAD中**: 1. 右键点击查询结果中的 `CLOB` 字段 2. 选择 **Open in Editor** 查看完整内容 --- #### **方法3:强制转换为VARCHAR2(慎用)** ```sql SELECT TO_CHAR(DBMS_METADATA.GET_DDL('TABLE', 'EMP')) AS DDL FROM DUAL; ``` ⚠️ 注意:`VARCHAR2` 最大支持4000字节,超长文本仍会被截断,仅适用于简单表结构。 --- #### **方法4:直接导出到文件** 在SQL*Plus中: ```sql SPOOL /path/to/output.sql SELECT DBMS_METADATA.GET_DDL('TABLE', 'EMP') FROM DUAL; SPOOL OFF ``` --- ### **高级配置** 通过元数据转换参数优化输出: ```sql BEGIN -- 禁用存储参数(减少输出长度) DBMS_METADATA.SET_TRANSFORM_PARAM( DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE', FALSE ); -- 禁用表空间参数 DBMS_METADATA.SET_TRANSFORM_PARAM( DBMS_METADATA.SESSION_TRANSFORM, 'TABLESPACE', FALSE ); END; / ``` --- ### **验证方法** 通过 `LENGTH` 函数检查实际长度: ```sql SELECT LENGTH(DBMS_METADATA.GET_DDL('TABLE', 'EMP')) AS DDL_LENGTH FROM DUAL; ``` 如果返回数值远大于客户端工具的显示限制,则确认是工具设置问题。 --- ### **最佳实践** 1. **优先使用SQL Developer** → 通过 **View > DDL** 自动生成完整SQL 2. **复杂对象导出** → 使用 `expdp` 数据泵工具: ```bash expdp user/password DIRECTORY=DATA_PUMP_DIR DUMPFILE=ddl.dmp CONTENT=METADATA_ONLY ``` 通过上述方法,可以彻底解决DDL语句被截断的问题。如果问题持续,请检查数据库版本(建议使用11g+)和工具兼容性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值