如何生成 Oracle 模式的整个 DDL(可编写脚本)?
Posted
技术标签:
【中文标题】如何生成 Oracle 模式的整个 DDL(可编写脚本)?【英文标题】:How to generate entire DDL of an Oracle schema (scriptable)? 【发布时间】:2012-06-08 19:55:03 【问题描述】:谁能告诉我如何为 Oracle 模式中的所有表、视图、索引、包、过程、函数、触发器、类型、序列、同义词、授权等生成 DDL?理想情况下,我也想复制行,但这不太重要。
我想在某种计划的作业上执行此操作,而不是每次都手动执行,因此排除了使用 SQL Developer 中的向导。
理想情况下,由于我将在多个相互具有授权和同义词的模式上运行它,我希望有一种方法可以在输出中进行查找/替换,以便模式名称与我的新名称相匹配模式将是。
谢谢!
【问题讨论】:
SQL Developer 可以通过它的命令行界面来做到这一点,所以如果你想走那条路是可能的。 简单运行:SELECT DBMS_METADATA.get_ddl(object_Type, object_name, owner) FROM ALL_OBJECTS WHERE OWNER = 'OWNER_NAME'; 【参考方案1】:首先导出架构元数据:
expdp dumpfile=filename logfile=logname directory=dir_name schemas=schema_name
然后使用 sqlfile
选项导入(它不会导入数据,只会将架构 DDL 写入该文件)
impdp dumpfile=filename logfile=logname directory=dir_name sqlfile=ddl.sql
【讨论】:
【参考方案2】:这个查询的输出很干净(原here)
clear screen
accept uname prompt 'Enter User Name : '
accept outfile prompt ' Output filename : '
spool &&outfile..gen
SET LONG 20000 LONGCHUNKSIZE 20000 PAGESIZE 0 LINESIZE 1000 FEEDBACK OFF VERIFY OFF TRIMSPOOL ON
BEGIN
DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform, 'SQLTERMINATOR', true);
DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform, 'PRETTY', true);
END;
/
SELECT dbms_metadata.get_ddl('USER','&&uname') FROM dual;
SELECT DBMS_METADATA.GET_GRANTED_DDL('SYSTEM_GRANT','&&uname') from dual;
SELECT DBMS_METADATA.GET_GRANTED_DDL('ROLE_GRANT','&&uname') from dual;
SELECT DBMS_METADATA.GET_GRANTED_DDL('OBJECT_GRANT','&&uname') from dual;
spool off
【讨论】:
这个脚本输出只会创建用户,不会创建用户的对象。【参考方案3】:您可以通过 SQL*Plus 和 dbms_metadata 包将模式输出到文件中。然后通过 sed 将架构名称替换为另一个名称。这适用于 Oracle 10 及更高版本。
sqlplus<<EOF
set long 100000
set head off
set echo off
set pagesize 0
set verify off
set feedback off
spool schema.out
select dbms_metadata.get_ddl(object_type, object_name, owner)
from
(
--Convert DBA_OBJECTS.OBJECT_TYPE to DBMS_METADATA object type:
select
owner,
--Java object names may need to be converted with DBMS_JAVA.LONGNAME.
--That code is not included since many database don't have Java installed.
object_name,
decode(object_type,
'DATABASE LINK', 'DB_LINK',
'JOB', 'PROCOBJ',
'RULE SET', 'PROCOBJ',
'RULE', 'PROCOBJ',
'EVALUATION CONTEXT', 'PROCOBJ',
'CREDENTIAL', 'PROCOBJ',
'CHAIN', 'PROCOBJ',
'PROGRAM', 'PROCOBJ',
'PACKAGE', 'PACKAGE_SPEC',
'PACKAGE BODY', 'PACKAGE_BODY',
'TYPE', 'TYPE_SPEC',
'TYPE BODY', 'TYPE_BODY',
'MATERIALIZED VIEW', 'MATERIALIZED_VIEW',
'QUEUE', 'AQ_QUEUE',
'JAVA CLASS', 'JAVA_CLASS',
'JAVA TYPE', 'JAVA_TYPE',
'JAVA SOURCE', 'JAVA_SOURCE',
'JAVA RESOURCE', 'JAVA_RESOURCE',
'XML SCHEMA', 'XMLSCHEMA',
object_type
) object_type
from dba_objects
where owner in ('OWNER1')
--These objects are included with other object types.
and object_type not in ('INDEX PARTITION','INDEX SUBPARTITION',
'LOB','LOB PARTITION','TABLE PARTITION','TABLE SUBPARTITION')
--Ignore system-generated types that support collection processing.
and not (object_type = 'TYPE' and object_name like 'SYS_PLSQL_%')
--Exclude nested tables, their DDL is part of their parent table.
and (owner, object_name) not in (select owner, table_name from dba_nested_tables)
--Exclude overflow segments, their DDL is part of their parent table.
and (owner, object_name) not in (select owner, table_name from dba_tables where iot_type = 'IOT_OVERFLOW')
)
order by owner, object_type, object_name;
spool off
quit
EOF
cat schema.out|sed 's/OWNER1/MYOWNER/g'>schema.out.change.sql
将所有内容放在脚本中并通过 cron(调度程序)运行。使用高级功能时,导出对象可能会很棘手。如果您需要在上述代码中添加更多异常,请不要感到惊讶。
【讨论】:
尽管我将 linesize 设置为 32767,但所有内容都会被包裹在 80 个字符左右。有什么办法解决这个问题吗? 我想将数据库从一台服务器复制到另一台服务器,所以这有帮助,但我需要按顺序排列数据库对象 - 手动不可能这样做,因为我有 1600 个数据库对象- 有没有办法让我们按顺序获取所有数据库对象脚本 - 它们是为一个特定的用户/模式创建的 @eisberg GRANT 语句可以使用以下命令获取:select dbms_metadata.get_dependent_ddl('OBJECT_GRANT', '<YOUR_TABLE_NAME>') from dual;
这很好!!!谢谢你。不过,我确实有一个问题,需要改变什么才能让他们导入它?【参考方案4】:
如果要为每个对象单独生成ddl,
查询是:
--为所有用户对象生成 DDL
--1。适用于所有表格
SELECT DBMS_METADATA.GET_DDL('TABLE', TABLE_NAME) FROM USER_TABLES;
--2。适用于所有索引
SELECT DBMS_METADATA.GET_DDL('INDEX', INDEX_NAME) FROM USER_INDEXES WHERE INDEX_TYPE ='NORMAL';
--3。适用于所有视图
SELECT DBMS_METADATA.GET_DDL('VIEW', VIEW_NAME) FROM USER_VIEWS;
或
SELECT TEXT FROM USER_VIEWS
--4。适用于所有实体化视图
SELECT QUERY FROM USER_MVIEWS
--5。适用于所有功能
SELECT DBMS_METADATA.GET_DDL('FUNCTION', OBJECT_NAME) FROM USER_PROCEDURES WHERE OBJECT_TYPE = 'FUNCTION'
================================================ ================================================
GET_DDL函数不支持某些object_type,如LOB、MATERIALIZED VIEW、TABLE PARTITION
所以,生成 DDL 的合并查询将是:
SELECT OBJECT_TYPE, OBJECT_NAME,DBMS_METADATA.GET_DDL(OBJECT_TYPE, OBJECT_NAME, OWNER)
FROM ALL_OBJECTS
WHERE (OWNER = 'XYZ') AND OBJECT_TYPE NOT IN('LOB','MATERIALIZED VIEW', 'TABLE PARTITION') ORDER BY OBJECT_TYPE, OBJECT_NAME;
【讨论】:
select dbms_metadata.get_ddl('MATERIALIZED_VIEW', 'MVIEW_NAME') from dual;作品 我想将一个数据库从一台服务器复制到另一台服务器,所以这有帮助,但我需要按顺序排列数据库对象 - 手动不可能这样做,因为我有 1600 个数据库对象- 有没有办法让我们按顺序获取所有数据库对象脚本 - 它们是为一个特定的用户/模式创建的 @gurupreet-singh-bhatia,这是否假定OWNER = 'XYZ'
将被替换为有效所有者?如果是这样,这是在哪里定义的?是用户吗?【参考方案5】:
要为整个 SCHEMA 即 USER 生成 DDL 脚本,您可以使用 dbms_metadata.get_ddl。
在Tim Hall创建的SQL*Plus中执行以下脚本:
在出现提示时提供用户名。
set long 20000 longchunksize 20000 pagesize 0 linesize 1000 feedback off verify off trimspool on
column ddl format a1000
begin
dbms_metadata.set_transform_param (dbms_metadata.session_transform, 'SQLTERMINATOR', true);
dbms_metadata.set_transform_param (dbms_metadata.session_transform, 'PRETTY', true);
end;
/
variable v_username VARCHAR2(30);
exec:v_username := upper('&1');
select dbms_metadata.get_ddl('USER', u.username) AS ddl
from dba_users u
where u.username = :v_username
union all
select dbms_metadata.get_granted_ddl('TABLESPACE_QUOTA', tq.username) AS ddl
from dba_ts_quotas tq
where tq.username = :v_username
and rownum = 1
union all
select dbms_metadata.get_granted_ddl('ROLE_GRANT', rp.grantee) AS ddl
from dba_role_privs rp
where rp.grantee = :v_username
and rownum = 1
union all
select dbms_metadata.get_granted_ddl('SYSTEM_GRANT', sp.grantee) AS ddl
from dba_sys_privs sp
where sp.grantee = :v_username
and rownum = 1
union all
select dbms_metadata.get_granted_ddl('OBJECT_GRANT', tp.grantee) AS ddl
from dba_tab_privs tp
where tp.grantee = :v_username
and rownum = 1
union all
select dbms_metadata.get_granted_ddl('DEFAULT_ROLE', rp.grantee) AS ddl
from dba_role_privs rp
where rp.grantee = :v_username
and rp.default_role = 'YES'
and rownum = 1
union all
select to_clob('/* Start profile creation script in case they are missing') AS ddl
from dba_users u
where u.username = :v_username
and u.profile <> 'DEFAULT'
and rownum = 1
union all
select dbms_metadata.get_ddl('PROFILE', u.profile) AS ddl
from dba_users u
where u.username = :v_username
and u.profile <> 'DEFAULT'
union all
select to_clob('End profile creation script */') AS ddl
from dba_users u
where u.username = :v_username
and u.profile <> 'DEFAULT'
and rownum = 1
/
set linesize 80 pagesize 14 feedback on trimspool on verify on
【讨论】:
【参考方案6】:PACKAGE 的 get_ddl 过程将返回规范和正文,因此最好更改对 all_objects 的查询,以便在选择时不返回包正文。
到目前为止,我将查询更改为:
SELECT DBMS_METADATA.GET_DDL(REPLACE(object_type, ' ', '_'), object_name, owner)
FROM all_OBJECTS
WHERE (OWNER = 'OWNER1')
and object_type not like '%PARTITION'
and object_type not like '%BODY'
order by object_type, object_name;
虽然根据您获得的对象类型可能需要进行其他更改...
【讨论】:
【参考方案7】:PACKAGE_BODY等对象有问题:
SELECT DBMS_METADATA.get_ddl(object_Type, object_name, owner) FROM ALL_OBJECTS WHERE OWNER = 'WEBSERVICE';
ORA-31600 invalid input value PACKAGE BODY parameter OBJECT_TYPE in function GET_DDL
ORA-06512: на "SYS.DBMS_METADATA", line 4018
ORA-06512: на "SYS.DBMS_METADATA", line 5843
ORA-06512: на line 1
31600. 00000 - "invalid input value %s for parameter %s in function %s"
*Cause: A NULL or invalid value was supplied for the parameter.
*Action: Correct the input value and try the call again.
SELECT DBMS_METADATA.GET_DDL(REPLACE(object_type,' ','_'), object_name, owner)
FROM all_OBJECTS
WHERE (OWNER = 'OWNER1');
【讨论】:
听起来你正在做某事,但它可能有助于扩展 PACKAGE_BODY 的“问题”并将 SQL 代码放在一个整洁的小代码块中。 您需要替换下划线的空格。尝试运行:“SELECT DBMS_METADATA.get_ddl(replace(object_Type, ' ', '_'), object_name, owner) FROM ALL_OBJECTS WHERE OWNER = 'WEBSERVICE';” 我的帖子正是关于它的以上是关于如何生成 Oracle 模式的整个 DDL(可编写脚本)?的主要内容,如果未能解决你的问题,请参考以下文章
如何检查分配给模式、oracle 数据库中角色的对象的权限(DDL、DML、DCL)?