使用脚本备份Oracle(插入语句,DDL)

时间:2016-04-15 09:07:08

标签: oracle plsql oracle-sqldeveloper

我想使用Insert和DDL语句备份数据库的一部分,其输出类似于使用TOAD或SQL Developer获得的输出,但是来自脚本。

详细说明: 这是为了能够看到源代码控制的变化和差异。 我们使用的是SQL Developer,LINUX工具和Python(使用Oracle)。

2 个答案:

答案 0 :(得分:1)

试试这个?根据需要更改设置。

导出架构:

1)在命令提示符下运行以下命令(但不是必需的)

SET NLS_LANG AMERICAN_AMERICA.UTF.8

2)一旦设置了以上,请运行以下操作。更改用户名/密码/ schemaname,导出路径

exp userid=<schemaname>/<pwd>@<dbname or SID> file=<localpath\1.dmp> 
    log=<localpath\2.log>  buffer=1000000000 feedback=25000 
    direct=y recordlength=64000 owner=<schemaname>

答案 1 :(得分:0)

必须有适合您尝试的工具(除了TOAD和PL / SQL)。

如果您打算为此编写代码,这是一个很棒的项目。你必须按照以下方式工作:

对于DDL

。编写一个脚本,列出您需要提取的所有对象;这将是表格,模式,程序,功能:

for x in (
    select * from dba_objects where object_type in ('PACKAGES', 'TABLES', '>others>') loop
     --- things to do with x.>columns<
end loop;

for u in (
    select * from dba_users where username in ( <list of needed schemas> ) loop
)
     --- things to do with users
end loop;

。然后从上面的列表中,您可以使用生成DDL的Oracle函数dbms_metadata.get_ddl。例如与用户:

begin
for u in (select * from dba_users where <list of needed schemas> 
              order by username)
    loop
      dbms_metadata.get_ddl('USER', u.username); 
    end loop;
end;

对于插入

(这可能需要一些时间来生成具有大型表的数据库(我的方法已有数千行)。

我建议你创建一个生成insert语句的泛型函数。只要它不包含BLOBCLOB,这就相当简单了。你拿每张表的每一列。

请记住以有序的方式生成插入,否则无法进行比较。

泛型函数应该以表格作为输入。从表名称中,它从dba_tables获取列,然后选择表。

--- plsql code below lists the columns of the tables
begin
    for t in (select * from dba_tables order by table_name) loop
        for c in (select * from dba_tab_columns where table_name=t.table_name and owner=t.owner order by owner, table_name, column_name) loop
            dbms_output.put_line(c.table_name||'.'||c.column_name);
        end loop;
    end loop;
end;

以下是如何在数组中收集值,然后在此数组上循环以将insert语句显示为文本(使用dbms_output.put_line)

declare
    type t_v is table of varchar2(32000);
    t_vchars t_v;
    v_ins varchar2(2000):=' ';
    v_sel varchar2(2000):=' ';
    v_res varchar2(4030):=' ';        
begin
    for t in (select * from dba_tables order by table_name) loop
        v_ins :='insert into '||t.table_name||'(';
        v_sel :=' select ';
        for c in (select * from dba_tab_columns where table_name=t.table_name and owner=t.owner) loop
            v_ins:= v_ins||c.column_name||',';
            v_sel:= v_sel||'''''''||'||c.column_name||'||'''''',';
        end loop;
        -- remove last comma
        v_ins:= substr(v_ins,1,length(v_ins)-1);
        v_sel:= substr(v_sel,1,length(v_sel)-1);
        v_ins:= v_ins||')';
        v_sel:= v_sel||' from dual';
        v_res:= 'select '''||v_ins||v_sel||''' from '||t.table_name;
        -- above, you still need to insert an order by, but I let you choose which solution 
        execute immediate v_res bulk collect into t_vchars;
        FOR i in 1..t_vchars.count LOOP
            dbms_output.put_line(t_vchars(i)||';');
        END LOOP;
    end loop;
end;

完成后,想要测试整个脚本。

当您想要测试和运行插入时,一个棘手的问题是您是否有外键。您必须在插入之前停用它们,否则您需要以有序的方式进行插入,这是不容易的。

for c in (select * from dba_constraints)
loop
   --- disable constraint
end loop;

插入完成后

for c in (select * from dba_constraints)
loop
   --- enable constraint
end loop;