原文:http://www.oracle.com/technetwork/issue-archive/2013/13-jan/o13asktom-1886639.html

I am using SQL Loader to load data into tables from a flat file. Some sample data in the file might be:

我打算使用SQL Loader装载来自平面文件数据。样例数据如下:

12,smith,1234556@@1234567 @@876556612,1200
14,John,1234@@4567@@56789 @@12345@@45778@@34566@@23456,1345






The field values are empno, empname, phone numbers, and salary. The table structures are

表结构如下:

create table emp ( empno number(5) primary key, ename varchar2(10), Sal number(10,2) )

create table emp_contact ( empno references emp, phone_no number(10) )





I want to insert the data into the emp and emp_contact tables. I don’t know how many values for phone_no the file contains (the number of values for phone_no is not fixed). How do I insert the data into the tables?

我想将以上数据分别装入2个表中: emp和emp_contact

问题是:我无法确定第三列(电话号码)有多少个,此列不固定。我将如何将数据装载进表?





这个问题很狡猾,看上去我们必须将第三列拆成多行插入。

对于号称“
21世纪神奇数据装载工具
--SQL Loader 来讲也无法直接实现!!!

此处,我建议使用21世纪数据装载工具
--外部表 解决。思路是:将平面文件装入外部表,然后通过编写SQL进行拆分,最后按特定插入规则一次性插入指定表中。

下面,看我演示:

--1)进行数据装载

create or replace directory my_dir as '/home/tkyte'

/





CREATE TABLE et

 ( "EMPNO" VARCHAR2(10),

   "ENAME" VARCHAR2(20),

   "TELNOS" VARCHAR2(1000),

   "SAL" VARCHAR2(10) )

 ORGANIZATION external

 (

   TYPE oracle_loader

   DEFAULT DIRECTORY MY_DIR

   ACCESS PARAMETERS

   (

     RECORDS DELIMITED BY NEWLINE CHARACTERSET US7ASCII

     BADFILE 'MY_DIR':'t.bad'

     LOGFILE 't.log_xt'

     READSIZE 1048576

     FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY '"' LDRTRIM

     MISSING FIELD VALUES ARE NULL

     REJECT ROWS WITH ALL NULL FIELDS

     (

       "EMPNO" CHAR(255)

         TERMINATED BY "," OPTIONALLY ENCLOSED BY '"',

       "ENAME" CHAR(255)

         TERMINATED BY "," OPTIONALLY ENCLOSED BY '"',

       "TELNOS" CHAR(1000)

         TERMINATED BY "," OPTIONALLY ENCLOSED BY '"',

       "SAL" CHAR(255)

         TERMINATED BY "," OPTIONALLY ENCLOSED BY '"'

     )

   )

   location

   (

     't.dat'

   )

 )

/





SQL> select * from et;





EMPNO  ENAME   TELNOS                                          SAL

—————  —————   —————————————————————————————————————————————   ————

12     smith   1234556@@1234567@@876556612                     1200

14     John    1234@@4567@@56789@@12345@@45778@@34566@@23456   1345





--2)编写拆分SQL

SQL> select empno, ename, sal, i,

       substr( tnos,

               instr( tnos, '@@', 1, i )+2,

               instr( tnos, '@@', 1, i+1 )

                 -instr( tnos, '@@', 1, i) - 2 ) tno

  from (

select to_number(et.empno) empno,

       et.ename,

       to_number(et.sal) sal,

       column_value i,

       '@@'||et.telnos||'@@' tnos

  from et,

       table( cast( multiset(

          select level

            from dual

         connect by level <=

            (length(et.telnos)

               -length(replace(et.telnos,'@@','')))/2+1 )

             as sys.odciNumberList ) )

       )

/





EMPNO  ENAME    SAL    I  TNO

—————  —————   ————   ——  ———————

   12  smith   1200    1  1234556

   12  smith   1200    2  1234567

   12  smith   1200    3  876556612

   14  John    1345    1  1234

   14  John    1345    2  4567

   14  John    1345    3  56789

   14  John    1345    4  12345

   14  John    1345    5  45778

   14  John    1345    6  34566

   14  John    1345    7  23456





10 rows selected.





--注意:这里使用了cast multiset语法,column_value是TABLE(odciNumberList)中一列









--3)编写插入SQL

SQL> create table emp

  2  ( empno number primary key,

  3    ename varchar2(10),

  4    sal   number

  5  );

Table created.





SQL> create table emp_contact

  2  ( empno    number references emp,

  3    phone_no number

  4  );

Table created.

\

SQL> insert all

when (i = 1) then into emp (empno,ename,sal) values (empno,ename,sal)

when (i > 0) then into emp_contact(empno,phone_no) values (empno,tno)

select empno, ename, sal, i,

       substr( tnos,

               instr( tnos, '@@', 1, i )+2,

               instr( tnos, '@@', 1, i+1 )

                 -instr( tnos, '@@', 1, i) - 2 ) tno

  from (

select to_number(et.empno) empno,

       et.ename,

       to_number(et.sal) sal,

       column_value i,

       '@@'||et.telnos||'@@' tnos

  from et,

       table( cast( multiset(

          select level

            from dual

         connect by level <=

            (length(et.telnos)

               -length(replace(et.telnos,'@@','')))/2+1 )

             as sys.odciNumberList ) )

       )

/

12 rows created.





SQL> select * from emp;





EMPNO  ENAME    SAL

—————  ——————  —————

   12  smith   1200

   14  John    1345





SQL> select * from emp_contact;





EMPNO    PHONE_NO

———————  —————————

   12     1234556

   12     1234567

   12   876556612

   14        1234

   14        4567

   14       56789

   14       12345

   14       45778

   14       34566

   14       23456

10 rows selected.

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

Dylan    Presents.

使用ORACLE外部表装载复杂数据的更多相关文章

  1. 如何利用Oracle外部表导入文本文件的数据

    同事最近在忙数据一致性比对工作,需要对不同文本文件中的数据进行比对,有的文件较大,记录较多,如果用普通的文本编辑器打开的话,很显然,会很卡,甚至打不开. 基于此,可将该文本文件的数据导入到数据库中,在 ...

  2. ORACLE外部表总结

    外部表介绍 ORACLE外部表用来存取数据库以外的文本文件(Text File)或ORACLE专属格式文件.因此,建立外部表时不会产生段.区.数据块等存储结构,只有与表相关的定义放在数据字典中.外部表 ...

  3. Oracle外部表详解(转载)

    (外部表创建主要注意创建目录访问权限问题.目录路径格式无空格等不相关字符,即必须是当前表访问用户可以访问:关于表中行数的限制问题,如果不加限制注意添加reject limit unlimited:表中 ...

  4. Oracle外部表详解

    外部表概述 外部表只能在Oracle 9i之后来使用.简单地说,外部表,是指不存在于数据库中的表.通过向Oracle提供描述外部表的元数据,我们可以把一个操作系统文件当成一个只读的数据库表,就像这些数 ...

  5. oracle外部表

    关于外部表的描述 正确描述 the create table as select statement can be used to upload data into a normal table in ...

  6. Oracle外部表的管理和应用

    外部表作为oracle的一种表类型,虽然不能像普通库表那么应用方便,但有时在数据迁移或数据加载时,也会带来极大的方便,有时比用sql*loader加载数据来的更为方便,下面就将建立和应用外部表的命令和 ...

  7. Oracle外部表的使用

    外部表可以像其它表一样,用select语句作查询.但不能做DML操作,不能建index,不接受约束.这是因为它不是以段的形式存于数据库中,只是以数据字典构造存在,指向一个或多个操作系统文件. 外部表的 ...

  8. 【原创】大叔经验分享(26)hive通过外部表读写elasticsearch数据

    hive通过外部表读写elasticsearch数据,和读写hbase数据差不多,差别是需要下载elasticsearch-hadoop-hive-6.6.2.jar,然后使用其中的EsStorage ...

  9. Oracle数据库表空间与数据文件的关系描述正确的是( )

    Oracle数据库表空间与数据文件的关系描述正确的是( ) A.一个表空间只能对应一个数据文件 B.一个表空间可以对应多个数据文件 C.一个数据文件可以对应多个表空间 D.表空间与数据文件没任何对应关 ...

  10. 使用oracle外部表进行数据泵卸载数据

    数据泵卸载Oracle9i引入了外部表,作为向数据库中读取数据的一种方法.Oracle 10g则从另一个方向引入了这个特性,可以使用CREATE TABLE语句创建外部数据,从而由数据库卸载数据.从O ...

随机推荐

  1. NodeJS安装指南(Mac)

    nvm,node,npm之间的区别 nvm:nodejs 版本管理工具. 也就是说:一个 nvm 可以管理很多 node 版本和 npm 版本. nodejs:在项目开发时的所需要的代码库 npm:n ...

  2. [转帖]等待事件 enq:TX - row lock contention分析与解决

    6月30日,数据库发生了大量锁表.大概持续1小时,并且越锁越多.后来通过业务人员停掉程序,并kill掉会话后解决. 几天后再EM上查看CPU占用: CPU发生了明显等待. 主要是由于enq:TX - ...

  3. [转帖]jmeter线程组与循环次数的区别

    在压测的时候,有些接口需要携带登录信息,但是我们只想登录一次,然后其他接口进行多用户压测,此时你会怎么办?用仅一次控制器实现吗?下面我们来看看用仅一次控制器能不能实现 压测时jmeter中的线程数是模 ...

  4. [转帖]Jmeter学习笔记(十)——元件的作用域和执行顺序

    https://www.cnblogs.com/pachongshangdexuebi/p/11582891.html jmeter是一个开源的性能测试工具,它可以通过鼠标拖拽来随意改变元件之间的顺序 ...

  5. [转帖]一个轻量的Linux运维监控脚本

    https://zhuanlan.zhihu.com/p/472040635 写在前面 我的需求 嗯,有几台很老的机器,上面部署的几个很老的应用 我需要每周对机器上的一些内存,磁盘,线程,应用和数据库 ...

  6. [转帖]Linux性能分析(二):理解CPU上下文切换

    在计算机中,上下文切换是指存储进程或线程的状态,以便以后可以还原它并从同一点恢复执行.这允许多个进程共享一个CPU,这是多任务操作系统的基本功能. Linux 是一个多任务操作系统,它支持远大于 CP ...

  7. Linux 安装宋体字体的简单办法

    1. 今天同事说测试环境(CentOS) 打印有异常,无法将汉字正常打印出来. 2. 开发同事提供的思路是安装上宋体的字体再进行尝试,并且给出了一个解决方案的地址: https://blog.csdn ...

  8. [Python] 基于RapidFuzz库实现字符串模糊匹配

    RapidFuzz是一个用于快速字符串模糊匹配的Python库,它能够快速计算两个字符串之间的相似度,并提供与Fuzzywuzzy(已停用)和TheFuzz(Fuzzywuzzy的升级版)类似的接口. ...

  9. [置顶] k8s,docker,微服务,监控

    综合 第一篇:k8s服务A内部调用服务B的方式 第二篇:go-zero grpc 第一篇:grpc,protobuf安装 第二篇:grpc签发证书 第三篇:golang-grpc 第四篇:python ...

  10. Linux挂载新磁盘到根目录

    1.添加磁盘到需要挂载的机器上2.lsblk查看硬盘挂载情况,sdb,sdc为我新挂载的磁盘 3.fdisk -l查看挂载之前的分区情况, 4.为新硬盘创建分区 fdisk /dev/sdb,终端会提 ...