最近遇到一个烫手的问题,Oracle 如何把 A 表数据弄到 B 中来,而且数据量非常大(大于1000w)说白了 就是旧库的数据挪到新数据库中来, 本来我写了一个这样的语句 INSERT INTO TABELA SELECT ....FORM TABLEB WHERE ROWNUM<=10000  这样些之后,我觉得还是不妥,如果中间出了什么问题了那就麻烦了。用 存储过程 或者 winform 写一个程序 来数据转移 我觉得安全性高一些。(这是我现在的思路)我想问问大神们 有没有什么好的工具 或者 思路 感谢回复!

解决方案 »

  1.   

    大数量数据使用导出(exp、expdp)导入(imp、impdp)在数据库之间转移数据最好导出:
    exp 用户名/密码@连接串 file=导出文件名 tables=(你的表名) direct=y recordlength=65535导入:
    imp 用户名/密码@连接串 file=要导入的件名 full=y ignore=y buffer=10485760
      

  2.   

    1、如果原表和目标标在不同的数据库或者不同的schema下面, 可以导入导出
    expdp/impdp 或者exp/imp 
    2、在同一个数据库且在同一个schema下面
       方法一
       导出表
       reanme 原表
       导入表
       如果不想影响其它人用,可以用下面脚步做。每次2w条,直到原表导完为止-- 基本格式 
    declare     -- 定义大数据表(Serv/Acct/Cust/Serv_resource_)的记录型变量
         TYPE ServArray     IS TABLE OF JK_PROD_RESOUCE_SUM_T%ROWTYPE;
         lServArray         ServArray;
         
         lLoopLimit         NUMBER(6);
         lLoopRows          NUMBER(9);
         
         -- 定义acct_t表的游标
         CURSOR CUR_SERV IS
         select * From JK_PROD_RESOUCE_SUM_T a;BEGIN
         -- 封存变量初始化
      
         lLoopRows    := 0;
         lLoopLimit   := 20000 ;
         OPEN CUR_SERV;
         LOOP
              FETCH CUR_SERV BULK COLLECT INTO lServArray LIMIT lLoopLimit;
              FORALL nServ IN 1 .. lServArray.COUNT
              INSERT /* + nologging parallel 16 */ INTO JK_PROD_RESOUCE_SUM_T1 VALUES lServArray(nServ);
              EXIT WHEN CUR_SERV%NOTFOUND;          lLoopRows := lLoopRows + lLoopLimit;
              
              -- 数据提交
              COMMIT;
         END LOOP;     CLOSE CUR_SERV;
            -- 提交数据
         COMMIT;
    END;
      

  3.   

    你有没第三方工具,比如TOAD,如果有,直接用其中的功能键很方便就能实现
      

  4.   

    导入导出方式 肯定不行 里面有1000w数据 写存储过程 貌似也不好管理 也许是我写的不够好吧。呵呵 恩 第三方工具 我用的是plsqldev 没用过TODA  如果结构完全不同,表里面的列和数据都有 那我们指定 就可以了 不指定肯定报错。 我现在直接写在程序里去了。思路是这样的:首先查出1w 然后插入进去 ,这一步走完之后,我会记住它最后一个ID是多少,然后第二次查得时候 在从这个开始查询 以及插入。 这样做有什么不好的,或者,大家还有什么好的建议 欢饮讨论 谢谢
      

  5.   

    1000W,数据一般用 存储过程 或者 winform 写一个程序 来数据转移 我觉得安全性高一些。你这样做,效率非常的差,什么场景,能用数据泵(EXP/EXPDP)?不行用SPOOL导出,然后再SQLDDR导入也快的
      

  6.   

    SPOOL导出 我也想过 但上面说不行。
      

  7.   

    还有个问题是 我现在可以循环读取100条 where rownum<=100 ,那最后小于100那些数据如何获取呢?
      

  8.   

    SELECT 其他字段
    FROM (
          SELECT rownum,其他字段
           FROM 你要操作的表
           WHERE rownum <= 200
         )
    WHERE rownum BETWEEN 101 AND 200;
    这是分页的做法。
      

  9.   

    ----先导出
    unload -u用户名/密码 -w"select * from table" -ftable
    生成table.txt,1000万的数据也就几百兆
    ----再导进
    unload -u用户名/密码 -ttable -cO
    sqlldr usrid=用户名/密码 control=table.ctl data=table.txt
    如果有没导进的,会有table.bad文件
      

  10.   

    1000w的数据不算特别多.用exp或者FETCH CUR_SERV BULK COLLECT INTO lServArray LIMIT 都可以.
    我一起在一家通讯公司做的时候,595 用哪个过程1000w通话记录,也就二十多分钟就可以了.
      

  11.   

    这个跟本不用写程序啊,除了用oracle本身的导入导出工具外,也可以将表的数据导到结构化的文件里,然后sqlldr装载也可以的。
      

  12.   

    1000W,用sqlldr 也就是几分钟的事。