sql loader从一行加载多行

时间:2013-12-02 16:14:02

标签: oracle

我在使用sql loader加载文件时遇到问题。

这就是我的输入文件:

#ID; CARD_NUMBER;USERNAME  
1;86730975,86536522,86793501;JOHN SMITH  
2;89734562;MICHAEL ABOT  
3;87903546,87265390;JAMES ALBERT  

加载后我想要实现的是:

#Table data
1;86730975;JOHN SMITH  
1;86536522;JOHN SMITH  
1;86793501;JOHN SMITH  
2;89734562;MICHAEL ABOT  
3;87903546;JAMES ALBERT  
3;87265390;JAMES ALBERT  

在使用Sql Loader之前我做了类似的事情,但我找不到源代码。所以,如果有人可以帮助我,那对我来说非常好。

我是这个论坛的新手,我不知道如何查找与我的用户名相关的所有帖子,如果有人可以提供帮助,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

您可以使用外部表格。对我个人而言,完成它将是一种更方便的方式:

  1. 在Oracle中创建一个指向服务器上文件的确切位置的目录。

    SQL> create or replace directory ff1 as 'c:\';
    
    directory created
    
  2. 创建类似于此的外部表:

    SQL> create table t1(
      2    t1_id      number,
      3    card_no    varchar2(4000),
      4    user_name  varchar2(4000)
      5  )
      6  organization external(
      7    type oracle_loader
      8    default directory ff1
      9    access parameters(
     10      records delimited by newline
     11      fields terminated by ';'
     12    )
     13    location('input.dat') --<-- file name
     14  ) reject limit unlimited
     15  ;
    
     Table created.
    
  3. 之后,您可以查询该外部表,并使用任何(有很多这样的)方法来拆分逗号分隔的字符串。在这种情况下,它将是card_number的值。例如:

    这是实际数据:

    SQL> column card_no format a40;
    SQL> column user_name format a17;
    
    SQL> select * from t1;
    
         T1_ID CARD_NO                                  USER_NAME
    ---------- ---------------------------------------- -----------------
             1 86730975,86536522,86793501               JOHN SMITH
             2 89734562                                 MICHAEL ABOT
             3 87903546,87265390                        JAMES ALBERT
    
    3 rows selected.
    

    实际数据的转换版本:

    SQL> column card_no format 9999999999;
    
    SQL> with ocrs(ocr) as(
      2    select level
      3      from ( select max(regexp_count(card_no, '[^,]+')) as mx
      4               from t1 ) s
      5     connect by level <= s.mx
      6  )
      7  select *
      8    from (select t.t1_id
      9               , to_number(regexp_substr(t.card_no, '[^,]+', 
     10                                         1, o.ocr)) as card_no
     11               , t.user_name
     12            from t1 t
     13           cross join ocrs o ) w
     14    where w.card_no is not null
     15   order by w.t1_id;
    

    结果:

          T1_ID     CARD_NO USER_NAME
    ----------- ----------- -----------------
              1    86730975 JOHN SMITH
              1    86793501 JOHN SMITH
              1    86536522 JOHN SMITH
              2    89734562 MICHAEL ABOT
              3    87265390 JAMES ALBERT
              3    87903546 JAMES ALBERT
    
    6 rows selected.
    

    完成此操作后,您可以使用简单的insert语句结合上述查询将新的转换数据插入另一个表中。

     insert into another_table(id, card_number, user_name)
        with ocrs(ocr) as(
          select level
        .....  
        /* the above query */