使用ORACLE外部表装载复杂数据

原文: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,[email protected]@1234567 @@876556612,1200

14,John,[email protected]@[email protected]@56789 @@[email protected]@[email protected]@[email protected]@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   [email protected]@[email protected]@876556612                     1200

14     John    [email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@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.

时间: 2024-08-05 06:19:47

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

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

同事最近在忙数据一致性比对工作,需要对不同文本文件中的数据进行比对,有的文件较大,记录较多,如果用普通的文本编辑器打开的话,很显然,会很卡,甚至打不开. 基于此,可将该文本文件的数据导入到数据库中,在集合的层面进行比对. 那么如何将文本文件的数据导入到数据库中呢?在这里,主要利用了Oracle的外部表特性. Oracle外部表支持两种类型的驱动:一种是ORACLE_LOADER,外部表的数据必须来源于文件文件,另一种则是ORACLE_DATAPUMP,外部表的数据必须是二进制dump文件,该du

ORACLE外部表总结

外部表介绍 ORACLE外部表用来存取数据库以外的文本文件(Text File)或ORACLE专属格式文 件.因此,建立外部表时不会产生段.区.数据块等存储结构,只有与表相关的定义放在数据字典中.外部表,顾名思义,存储在数据库外面的表.当存取时才能从 ORACLE专属格式文件中取得数据,外部表仅供查询,不能对外部表的内容进行修改(INSERT.UPDATE.DELETE操作).不能对外部表建立 索引.因为创建索引就意味着要存在对应的索引记录.而外部表其实在没有存储在数据库中.故在外部是无法建立索

Oracle外部表详解(转载)

(外部表创建主要注意创建目录访问权限问题.目录路径格式无空格等不相关字符,即必须是当前表访问用户可以访问:关于表中行数的限制问题,如果不加限制注意添加reject limit unlimited:表中数据格式与创建表时access parameters中的定义需保持同步,适当用skip=1) 外部表概述 外部表只能在Oracle 9i之后来使用.简单地说,外部表,是指不存在于数据库中的表.通过向Oracle提供描述外部表的元数据,我们可以把一个操作系统文件当成一个只读的数据库表,就像这些数据存储

PLSQL_Oracle外部表的概念和使用(案例)(通过外部表直接查询数据文件以节数据库表空间)

2014-08-25 BaoXinjian 一.摘要 ORACLE外部表用来存取数据库以外的文本文件(Text File)或ORACLE专属格式文件. 因此,建立外部表时不会产生段.区.数据块等存储结构,只有与表相关的定义放在数据字典中. 外部表,顾名思义,存储在数据库外面的表. 当存取时才能从ORACLE专属格式文件中取得数据,外部表仅供查询,不能对外部表的内容进行修改(INSERT.UPDATE.DELETE操作). 不能对外部表建立索引.因为创建索引就意味着要存在对应的索引记录.而外部表其

Oracle外部表

1.外部表简介 外部表是Oracle9i之后来使用的.外部表是一类表的定义存在于数据库而数据不存在于数据库的表. 在数据库操作过程中可以对外部表进行select,join,sort操作也可以对外部表创建视图和同义词.但是不能在外部表上进行DML操作和创建索引. 外部表提供两种访问驱动.一种ORACLE_LOADER另一种ORACLE_DATAPUMP.默认驱动是ORACLE_LOADER. ORACLE_LOADER驱动从外部文件中读数据.ORACLE_LOADER创建外部表的语法和SQL*Lo

Oracle外部表的管理和应用

外部表作为oracle的一种表类型,虽然不能像普通库表那么应用方便,但有时在数据迁移或数据加载时,也会带来极大的方便,有时比用sql*loader加载数据来的更为方便,下面就将建立和应用外部表的命令和操作记录如下: --创建存放文件的directory对象 sqlplus username/[email protected] create directory ex_data as '/home/ex_data/'; --创建外部表 CREATE TABLE tab1_ex ( C1 VARCHA

zbb20170816 oracle Oracle 查看表空间、数据文件的大小及使用情况sql语句

oracle Oracle 查看表空间.数据文件的大小及使用情况sql语句 --表空间 --1G=1024MB --1M=1024KB --1K=1024Bytes --1M=11048576Bytes --1G=1024*11048576Bytes=11313741824Bytes SELECT a.tablespace_name "表空间名", total "表空间大小", free "表空间剩余大小", (total - free) &qu

oracle 外部表

语法: create table 表名( 列名1,列名2,...... ) organization external  ###说明创建外部表 ( type 访问类型            ###一般是 ORACLE_LOADER ,ORACLE_DATAPUMP default directory   路径名   ####指定默认目录对象 access parameter (        ###数据源文件与表中行之间的映射关系 records delimited by 设置分隔符    ##

ORACLE - 管理表空间和数据文件

ORACLE表空间是一个逻辑分区,一个数据文件只能属于一个表空间,一个表空间可以拥有多个数据文件. 一般情况下,如果一个实例分配给多个应用使用,需要创建不同的表空间,每个用户使用自己的表空间. 一.表空间的创建与授权 首先查看表空间的使用情况: select tablespace_name,sum(bytes)/1024/1024 as MB from dba_data_files group by tablespace_name; ---剩余容量(在固定大小的情况下) select table