您的位置:首页 > 数据库 > Oracle

ORACLE EXP IMP 导入导出数据 解决如何导出空表

2015-03-13 09:51 519 查看
转载:http://blog.csdn.net/yudehui/article/details/8078294

需求:

20110830

以前有实验过exp/imp该工具,但是没有成功,是因为有些表没有导出来,怕一个个查麻烦,也没有去找规律。当时的实验环境是oracle11g

今天叫孙捷琳搞数据库,要插入中国的乡村数据,那个数据量很大,用sql复制进去然后插入,是可以实现,但是速度太慢了。没有效率

吴强建议说,用exp/imp,我自己也想了,然后网络上找了exp/imp,sqlloader等方法。

今天exp/imp实验成功,过程如下

1、导入导出(imp/exp) 某个用户表下面的所有数据

导出某个用户的所有对象


[oracle@cddserver1 ~]$ echo $NLS_LANG

AMERICAN_AMERICA.ZHS16GBK

[oracle@cddserver1 ~]$ exp testa/testa@orcl owner=[b] testa file=/home/oracle/testa.dmp
[/b]

导入某个用户的数据

[oracle@cddserver1 ~]$imp testa/testa fromuser =testa touser =testa file=/home/oracle/testa.dmp

注意:

要保证导入的用户的表空间的名称和导出的表空间名称是一样的

导入前最好保证要导入用户里面没有重复的对象和数据,要不导入会不成功。

 11G中有个新特性,当表无数据时,不分配segment,以节省空间,这样就会没有导出数据 

2、导出和导入某个用户下的某张表

[oracle@developserver ~]$  exp test/test file=/home/oracle/Desktop/t_area.dmp log=t_area.log tables=t_area

[oracle@developserver ~]$ imp  file=/home/oracle/Desktop/t_area.dmp tables=t_area commit=y ignore=y

注意导入之前最好保证表中的数据为空 

3、解决使用oracle11g无法导出(exp/imp)空表的问题

解决方法,原理就是往所有的空表中插入数据:

搞了我好久,最后查到这个方法。

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

方法1:

在图形工具中,如sqldeveloper,pl/sqldeveloper用以下这句查找空表

select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0

把查询结果导出,就是把语句复制出来单独运行

方法2:

sqlplus 中执行下面的程序

--查询当前用户下的所有空表,并生成空表的插入语句脚本

create or replace

procedure  generate_tab_segement is

v_table                      NVARCHAR2(200);

v_sql                        VARCHAR2(200);

v_q                          NUMBER;

v_char_value                 NVARCHAR2(10);

v_varchar2_value             NVARCHAR2(10);

v_number_value               NVARCHAR2(10);

v_date_value                 NVARCHAR2(10);

v_add_value                  NVARCHAR2(10);

v_separate_value             NVARCHAR2(10);

v_insert_sql                 NVARCHAR2(4000);

col_num                      NVARCHAR2(200);

tb_name                      NVARCHAR2(200);

TYPE TCUR IS REF CURSOR; 

c2 TCUR;

begin

     FOR r1 IN (SELECT table_name tn FROM tabs) LOOP

        BEGIN

            v_table   :=r1.tn;

            v_sql     := 'SELECT count(*) as q FROM ' || v_table || ' where rownum = 1';

            v_char_value := '''1''';

            v_varchar2_value := '''1''';

            v_number_value := '1';

            v_date_value := 'sysdate';

            v_separate_value := ',';

            v_insert_sql := 'insert into ';

            v_add_value :='null';

            OPEN c2 FOR v_sql ; 

            LOOP

                FETCH c2 INTO v_q;

                EXIT WHEN c2%NOTFOUND;

                IF v_q = 0 THEN

                    --DBMS_OUTPUT.PUT_LINE(v_table);

                    --构造插入行

                    FOR user_null_table IN (select to_char(count(*)) as col_num,

                    t.TABLE_NAME as tb_name

                    from user_tab_columns t

                    where t.TABLE_NAME= v_table

                    group by t.TABLE_NAME) LOOP

                        BEGIN

                            col_num      := user_null_table.col_num;

                            tb_name      := user_null_table.tb_name;

                            v_insert_sql := 'insert into ';

                            v_insert_sql := v_insert_sql || tb_name || ' values(' ;

                            FOR user_tab_cols IN (select * from user_tab_columns t where t.TABLE_NAME = tb_name ORDER BY t.COLUMN_ID) LOOP

                                BEGIN                                                                   

                                    v_add_value :='null';                                    

                                    IF user_tab_cols.COLUMN_ID = col_num THEN 

                                       v_separate_value := '';

                                    else

                                        v_separate_value := ',';

                                    END IF;                                   

                                    if user_tab_cols.DATA_TYPE = 'CHAR' THEN

                                        v_add_value := v_char_value;

                                    END if;

                                    

                                    IF user_tab_cols.DATA_TYPE = 'VARCHAR2' THEN

                                        v_add_value := v_varchar2_value;

                                    END if;                                    

                                    IF user_tab_cols.DATA_TYPE = 'NVARCHAR2' THEN

                                        v_add_value := v_varchar2_value;

                                    END if;                                    

                                    IF user_tab_cols.DATA_TYPE = 'NUMBER' THEN

                                        v_add_value := v_number_value;

                                    END if;                                    

                                    IF user_tab_cols.DATA_TYPE = 'LONG' THEN

                                        v_add_value := v_number_value;

                                    END if;                                    

                                    IF user_tab_cols.DATA_TYPE = 'DATE' THEN

                                        v_add_value := v_date_value;

                                    END IF;                                    

                                    IF substr(user_tab_cols.DATA_TYPE,0,9) = 'TIMESTAMP' THEN

                                        v_add_value := v_date_value;

                                    END IF;                                   

                                    v_insert_sql := v_insert_sql || v_add_value ||

                                        v_separate_value;                                

                                end;

                            END LOOP;                            

                            v_insert_sql := v_insert_sql || ');';

                            DBMS_OUTPUT.PUT_LINE(v_insert_sql);                           

                        end;

                    END LOOP;                

                end if;

            END LOOP;

            CLOSE c2;

        end;

    END LOOP;

end generate_tab_segement;

/

然后用图形界面工具去调用该存储过程,让存储过程语句执行一次,并起作用,不知道什么原因有些表的数据没有插入进去,为了保证不会出错,大家可以将执行完显示的SQL语句在执行一次就绝对不会错误。

然后将执行完的结果复制一次,在用图形界面执行一次,就可以了

 方法3:默认给任何空表都分配空间

设置deferred_segment_creation 参数

SQL> alter system set deferred_segment_creation=false;

SQL> show parameter deferred_segment_creation

NAME                                 TYPE        VALUE

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

deferred_segment_creation            boolean     FALSE 

该参数值默认是TRUE,当改为FALSE时,无论是空表还是非空表,都分配segment。

需注意的是:该值设置后对以前导入的空表不产生作用,仍不能导出,只能对后面新增的表产生作用。如需导出之前的空表,只能用第一种方法。

参考
http://blog.csdn.net/wyzxg/article/details/2123403 http://blog.csdn.net/dws2004/article/details/6315706
http://tech.ddvip.com/2008-08/121991685458513.html 
http://hi.baidu.com/aweiwenyuan/blog/item/e115ec526b5e830b0df3e302.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: