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

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

基于此,可将该文本文件的数据导入到数据库中,在集合的层面进行比对。

那么如何将文本文件的数据导入到数据库中呢?在这里,主要利用了Oracle的外部表特性。

Oracle外部表支持两种类型的驱动:一种是ORACLE_LOADER,外部表的数据必须来源于文件文件,另一种则是ORACLE_DATAPUMP,外部表的数据必须是二进制dump文件,该dump文件是先前将Oracle内部表的数据导入到外部表中填充的文件。很显然,Oracle希望将数据保留在数据库内部进行处理。

首先,我们来看一下该文本文件的大小及记录。

[[email protected] ~]$ du -sm P_20150626010000_2002371.0003479598
274    P_20150626010000_2002371.0003479598
[[email protected] ~]$ wc -l P_20150626010000_2002371.0003479598
2899265 P_20150626010000_2002371.0003479598

从上面的输出可以看出,该文件274M,有2899265条记录。

其次,构建创建外部表语句。

CREATE TABLE emp_load
   (subsid number(18),
    servnumber VARCHAR2(20 CHAR),
    subsprodid NUMBER(18),
    prodid VARCHAR2(32 CHAR),
    startdate date,
    enddate  date,
    owner VARCHAR2(4 CHAR))
ORGANIZATION EXTERNAL
   (TYPE ORACLE_LOADER
    DEFAULT DIRECTORY tmp
    ACCESS PARAMETERS
      (RECORDS DELIMITED BY NEWLINE
        FIELDS TERMINATED BY "|"
             ( subsid      DECIMAL EXTERNAL,
               servnumber  CHAR(20),
               subsprodid  DECIMAL EXTERNAL,
               prodid  CHAR(32),
                startdate date "yyyymmddhh24miss",
               enddate date "yyyymmddhh24miss",
               owner   CHAR(4)
              )
      )
    LOCATION (‘P_20150626010000_2002371.0003479598‘)
   );
 

注意,目录tmp必须存在,因为我是在scott用户下执行的,所以scott用户必须对该路径有读写权限。

第三、在scott用户下执行该建表语句。

第四、查看生成的外部表是否有问题

SQL> select count(*) from emp_load;

      COUNT(*)
------------------
       2899265

记录与wc-l查看的记录数吻合。

注意,建表过程中没有报错并不一定意味着数据已经成功加载在外部表中。必须通过查询外部表来判定数据是否已成功加载,倘若有错误提示,可参看当前目录下生成的日志文件,具体在本例中,是EMP_LOAD_2000.bad和EMP_LOAD_2000.log。

当然,外部表中的数据只能查询,不能做DML操作,譬如,随机删除表中的一条数据

SQL> delete from emp_load where rownum=1;
delete from emp_load where rownum=1
            *
ERROR at line 1:
ORA-30657: operation not supported on external organized table

如果想对该外部表数据进行DML操作,可先将外部表的数据导入到内部表中。具体步骤如下:

SQL> create table test as select * from emp_load where 1=0;

Table created.

SQL> INSERT /*+ APPEND */ INTO test select * from emp_load;

2899265 rows created.

Elapsed: 00:01:00.29
SQL> select * from test where rownum<=100;
select * from test where rownum<=100
              *
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying it in parallel

SQL> commit;

Commit complete.

SQL> select * from test where rownum<=100;

在这里,为了节省时间,我用了直接路径插入,可以看出,插入近300万数据,只用了1分左右的时间,考虑到我虚拟机上的数据库,只给它分配了300M的内存,加载的效率还是相当可观的。

SQL> show parameter memory

NAME                     TYPE     VALUE
------------------------------------ ----------- ------------------------------
hi_shared_memory_address         integer     0
memory_max_target             big integer 300M
memory_target                 big integer 300M
shared_memory_address             integer     0

后来,测试了一下传统路径插入所消耗的时间,为了和直接路径插入进行比较,剔除SQL解析,data buffer等因素的影响,清空了共享池和buffer cache,具体如下:

SQL> conn /as sysdba
Connected.
SQL> alter system flush shared_pool;

System altered.

SQL> alter system flush buffer_cache;

System altered.

SQL> conn scott/tiger
Connected.
SQL> set timing on
SQL> insert into test select * from emp_load;

2899265 rows created.

Elapsed: 00:01:05.36

用传统路径插入(即会产生redo日志),耗时1分5秒,相对于直接路径插入,两者效率相差不大,看来还是数据量较小,不能明显的体现直接路径插入速度上的优势。

注意:在SQL*PLUS中,number字段的输出默认为10,这样会导致对于937116510102250300这样的数值,可能会显示为9.3712E+17,在这里,可通过set numwidth 18来显示完整的number字段的值。

时间: 2024-12-24 11:33:10

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

Oracle外部表详解(转载)

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

ORACLE外部表总结

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

oracle数据库表中,插入数据的时候如何产生一个 字母+数字 编号?

Oracle 语句中"||"代表什么啊? oracle数据库表中,插入数据的时候如何产生一个 字母+数字 编号? 排序的话,用order by来处理即可.比如:cola123a234b999b335select * from tablename order by col; 结果就是 cola123a234b335b999 如果按倒序排列:select * from tablename order by col desc; 结果就是 colb999b335a234a123 其他回答 先创

oracle 外部表之 sqlldr 生成

oracle的导入工具,速度挺快,这里记一下外部表的使用,通常外部表要记的语法太多例如: CREATE TABLE PROD_MASTER ( "EMPNO" NUMBER, "ENAME" VARCHAR2(50), "HIREDATE" DATE, "DEPTNO" NUMBER ) ORGANIZATION external ( TYPE oracle_loader DEFAULT DIRECTORY ext_table

oracle 外部表

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

oracle 外部表查alter日志

--创建文件夹,路径是alter日志的路径 create or replace directory data_dir as '/u01/app/oracle/diag/rdbms/orcl/orcl/trace'; --创建外部表 create table alert_log( text_line varchar2(225) ) organization external ( TYPE ORACLE_LOADER DEFAULT DIRECTORY DATA_DIR ACCESS PARAMET

利用Oracle创建表空间和用户

第一步,创建表空间 以SYS/sys账户和SYSDBA身份登录OEM,通过"管理"-"数据库管理"-"存储"-"表空间"打开表空间创建界面, 选择"创建",进入"创建 表空间"界面, 在"创建 表空间"界面"一般信息"选项的"名称"处填写所要创建的表空间名,如DYZJDGG,"区管理"."类型&qu

使用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]

Oracle外部表

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