Oracle DB 外部表详解

Oracle 数据泵导出表部分列的实现方案:从 12c 新特性到低版本兼容 本文介绍了Oracle数据库中导出表部分列数据的三种解决方案。针对12c及以上版本,推荐使用VIEWS_AS_TABLES参数,通过创建视图导出指定列数据,无需创建临时表,支持直接导入;11g/10g版本可采用ORACLE_DATAPUMP外部表方式,实现跨版本兼容;9i及以下版本则需借助临时表+exp/imp的传统方式。文中详细说明了每种方案的具体实现步骤和注意事项,建议根据数据库版本选择最优方法,以提升数据迁移效率并减少存储占用。 阅读详情

来自一泽涟漪的博客:http://www.cnblogs.com/ilifeilong/p/7648193.html

外部表概述

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

外部表的特性 

位于文件系统之中,按一定格式分割,如文本文件或者其他类型的表可以作为外部表。
对外部表的访问可以通过SQL语句来完成,而不需要先将外部表中的数据装载进数据库中。
外部数据表都是只读的,因此在外部表不能够执行DML操作,也不能创建索引。
ANALYZE语句不支持采集外部表的统计数据,应该使用DMBS_STATS包来采集外部表的统计数据。

创建外部表的注意事项 

1.需要先建立目录对象

在建立对象的时候,需要小心,Oracle数据库系统不会去确认这个目录是否真的存在。如果在输入这个目录对象的时候,不小心把路径写错了,那可能这个外 部表仍然可以正常建立,但是却无法查询到数据。由于建立目录对象时,缺乏这种自我检查的机制,为此在将路径赋予给这个目录对象时,需要特别的注意。另外需 要注意的是路径的大小写。在Windows操作系统中,其路径是不区分大小写的。而在Linux操作系统,这个路径需要区分大小写。故在不同的操作系统 中,建立目录对象时需要注意这个大小写的差异

2.对于操作系统文件的要求

建立外部表时,必须指定操作系统文件所使用的分隔符号。并且该分隔符有且只有一个。创建外部表时,不能含有标题列。如果这个标题信息与外部表的字段类型不一致(如字段内容是number数据类型,而标题信息则是字符型数据,则在查询时就会出错)。如果数据类型恰巧一致的话,这个标题信息Oracle数据库也会当作普通记录来对待。

当Oracle数据库系统访问这个操作系统文件的时候,会在这个文件所在的目录自动创建一个日志文件。无论最后是否访问成功,这个日志文件都会如期建立。查看这个日志文件,可以了解数据库访问外部表的频率、是否成功访问等等。默认情况下,该日志在与外部表的相同directory下产生。

3.在建立临时表时的相关限制

对表中字段的名称存在特殊字符的情况下,必须使用英文状态的下的双引号将该表列名称连接起来。如采用”SalseID#”。
对于列名字中特殊符号未采用双引号括起来时,会导致无法正常查询数据。
建议不用使用特殊的列标题字符
在创建外部表的时候,并没有在数据库中创建表,也不会为外部表分配任何的存储空间。
创建外部表只是在数据字典中创建了外部表的元数据,以便对应访问外部表中的数据,而不在数据库中存储外部表的数据。
简单地说,数据库存储的只是与外部文件的一种对应关系,如字段与字段的对应关系。而没有存储实际的数据。
由于存储实际数据,故无法为外部表创建索引,同时在数据使用DML时也不支持对外部表的插入、更新、删除等操作。

4.删除外部表或者目录对象

一般情况下,先删除外部表,然后再删除目录对象,如果目录对象中有多个表,应删除所有表之后再删除目录对象。
如果在未删除外部表的情况下,强制删除了目录,在查询到被删除的外部表时,将收到"对象不存在"的错误信息。
查询dba_external_locations来获得当前所有的目录对象以及相关的外部表,同时会给出这些外部表所对应的操作系统文件的名字。 如果只是在数据库层面上删除外部表,并不会自动删除操作系统上的外部表文件。

 5.对于操作系统平台的限制

不同的操作系统对于外部表有不同的解释和显示方式
如在Linux操作系统中创建的文件是分号分隔且每行一条记录,但该文件在Windows操作系统上打开则并非如此。
建议避免不同操作系统以及不同字符集所带来的影响

创建外部表 

使用CREATE TABLE语句的ORGANIZATION EXTENERAL子句来创建外部表。外部表不分配任何盘区,因为仅仅是在数据字典中创建元数据。

1.外部表的创建语法

create table table_name
           (col1 datatype1,col2 datatype2,col3 datatype3)
            organization external
           (.....)
详细语法可参见笔者的另两篇文章

Oracle外部表ORACLE_DATAPUMP类型的创建语法详解:http://czmmiao.iteye.com/blog/1268453

Oracle外部表ORACLE_LOADER类型的创建语法详解:http://czmmiao.iteye.com/blog/1268157

2.由查询结果集,使用Oracle_datapump来填充数据来生成外部表

a.创建系统目录以及Oracle数据目录名来建立对应关系,同时授予权限
$ mkdir -p /home/oracle/external_tb/data
create or replace directory data_dir as '/home/oracle/external_tb/data/';
grant read,write on directory data_dir to scott;
b.创建外部表
复制代码
create table ex_tb1
            (ename,job,sal,dname)
            organization external
            (type oracle_datapump default directory data_dir location('ex_tb1'))
            parallel 1
            as select ename,job,sal,dname from emp join dept on emp.deptno=dept.deptno;
复制代码
c.验证外部表
复制代码
select * from ex_tb1;

ENAME                       JOB           SAL  DNAME
------------------------- -------------------- ---- -------------------------
CLARK                  MANAGER              2450 ACCOUNTING
KING                     PRESIDENT             5000 ACCOUNTING
MILLER                   CLERK                 1300 ACCOUNTING
JONES                    MANAGER               2975 RESEARCH
FORD                     ANALYST               3000 RESEARCH
ADAMS                    CLERK                 1100 RESEARCH
SMITH                    CLERK                  800 RESEARCH
SCOTT                    ANALYST               3000 RESEARCH
WARD                     SALESMAN              1250 SALES
TURNER                   SALESMAN              1500 SALES
ALLEN                    SALESMAN              1600 SALES
JAMES                    CLERK                  950 SALES
BLAKE                    MANAGER               2850 SALES
MARTIN                   SALESMAN              1250 SALES

14 rows selected.
复制代码

对于使用上述方式创建的外部表可以将其复制到其他路径作为外部表的原始数据来生成新的外部表,用于转移数据。

d.将外部表文件复制一个新的文件名,用以模拟到其他服务器上
$ cp /home/oracle/external_tb/data/ex_tb1 /home/oracle/external_tb/data/in_tb1
e. 新建表,将上述外部表的数据导入到新表中
create table in_tb1
            (ename varchar2(10),job varchar2(9),sal number(7,2),dname varchar(14))
            organization external
            (type oracle_datapump default directory data_dir location('in_tb1'));
f.验证新外部表的数据
复制代码
select * from in_tb1;

ENAME                       JOB           SAL  DNAME
------------------------- -------------------- ---- -------------------------
CLARK                  MANAGER              2450 ACCOUNTING
KING                     PRESIDENT             5000 ACCOUNTING
MILLER                   CLERK                 1300 ACCOUNTING
JONES                    MANAGER               2975 RESEARCH
FORD                     ANALYST               3000 RESEARCH
ADAMS                    CLERK                 1100 RESEARCH
SMITH                    CLERK                  800 RESEARCH
SCOTT                    ANALYST               3000 RESEARCH
WARD                     SALESMAN              1250 SALES
TURNER                   SALESMAN              1500 SALES
ALLEN                    SALESMAN              1600 SALES
JAMES                    CLERK                  950 SALES
BLAKE                    MANAGER               2850 SALES
MARTIN                   SALESMAN              1250 SALES

14 rows selected.
复制代码
g.创建正常的表,将外部表数据导入,这就是利用ORACLE_DATAPUMP类型的额外部表实现数据迁移
create table tb1 as select * from in_tb1;

3.使用外部文件数据,使用oracle_loader来填充数据来生成外部表

 a.准备外部数据源文件
复制代码
cat /home/oracle/external_tb/data/1.txt
"7369","SMITH","CLERK","7902","17-DEC-80","100","0","20"
"7499","ALLEN","SALESMAN","7698","20-FEB-81","250","0","30"
"7521","WARD","SALESMAN","7698","22-FEB-81","450","0","30"
"7566","JONES","MANAGER","7839","02-APR-81","1150","0","20"

$ cat /home/oracle/external_tb/data/2.txt
"7654","MARTIN","SALESMAN","7698","28-SEP-81","1250","0","30"
"7698","BLAKE","MANAGER","7839","01-MAY-81","1550","0","30"
"7934","MILLER","CLERK","7782","23-JAN-82","3500","0","10"
复制代码
b.创建外部表
复制代码
create table emp_new(
                    emp_id number(4),
                    ename varchar2(15),
                    job varchar2(12),
                    mgr_id number(4),
                    hiredate date,
                    salary number(8),
                    comm number(8),
                    dept_id number(2)
                    )
            organization external
                    (
                    type oracle_loader
                    default directory data_dir
                    access parameters(
                                    records delimited by newline
                                    badfile 'emp_new%a_%p.bad'
                                    logfile 'emp_new%a_%p.log'
                                    fields terminated by ','
                                    optionally enclosed by '"'
                                    lrtrim missing field values are null
                                    reject rows with all null fields
                                    )
                    location ('1.txt','2.txt')
)
parallel 
reject limit unlimited;
复制代码
c.验证外部表
复制代码
select * from emp_new;

EMP_ID ENAME      JOB              MGR_ID    HIREDATE            SALARY     COMM       DEPT_ID
------ ---------- --------------- ---------- ------------------- ---------- ---------- ----------
  7654 MARTIN     SALESMAN        7698       1981-09-28 00:00:00 1250       0           30
  7698 BLAKE      MANAGER         7839       1981-05-01 00:00:00 1550       0           30
  7934 MILLER     CLERK           7782       1982-01-23 00:00:00 3500       0           10
  7369 SMITH      CLERK           7902       1980-12-17 00:00:00 100        0           20
  7499 ALLEN      SALESMAN        7698       1981-02-20 00:00:00 250        0           30
  7521 WARD       SALESMAN        7698       1981-02-22 00:00:00 450        0           30
  7566 JONES      MANAGER         7839       1981-04-02 00:00:00 1150       0           20

7 rows selected.
复制代码

 4.外部表相关视图

a.查看外部表信息
select TABLE_NAME,TYPE_NAME,DEFAULT_DIRECTORY_NAME,REJECT_LIMIT,ACCESS_PARAMETERS from user_external_tables;

 

b.获得平面文件的位置
复制代码
select * from user_external_locations order by table_name;

TABLE_NAME LOCATION   DIRECTORY DIRECTORY_NAME
---------- ---------- --------- --------------------
EMP_NEW    1.txt      SYS       DATA_DIR
EMP_NEW    2.txt      SYS       DATA_DIR
EX_TB1     ex_tb1     SYS       DATA_DIR
IN_TB1     in_tb1     SYS       DATA_DIR
复制代码

 

外部表定义的几个重点 

1.ORGANIZATION EXTERNAL关键字,必须要有。以表明定义的表为外部表。

2..重要参数外部表的类型

ORACLE_LOADER:定义外部表的缺省方式,只能只读方式实现文本数据的装载。
ORACLE_DATAPUMP:支持对数据的装载与卸载,数据文件必须为二进制dump文件。可以从外部表提取数据装载到内部表,也可以从内部表卸载数据作为二进制文件填充到外部表。

3.DEFAULT DIRECTORY:缺省的目录指明了外部文件所在的路径

4.LOCATION:定义了外部表的位置

5.ACCESS PARAMETERS:描述如何对外部表进行访问

RECORDS关键字后定义如何识别数据行  
DELIMITED BY 'XXX'——换行符,常用newline定义换行,并指明字符集。对于特殊的字符则需要单独定义,如特殊符号,可以使用OX'十六位值',例如tab(/t)的十六位是9,则DELIMITEDBY0X'09';
cr(/r)的十六位是d,那么就是DELIMITEDBY0X'0D'。
SKIP X ——跳过X行数据,有些文件中第一行是列名,需要跳过第一行,则使用SKIP 1。
FIELDS关键字后定义如何识别字段,常用的如下:
FIELDS:TERMINATED BY 'x'——字段分割符。
ENCLOSED BY 'x'——字段引用符,包含在此符号内的数据都当成一个字段。
例如一行数据格式如:"abc","a""b,""c,"。使用参数TERMINATED BY ',' ENCLOSED BY '"'后,系统会读到两个字段,第一个字段的值是abc,第二个字段值是a"b,"c,。
LRTRIM ——删除首尾空白字符。
MISSING FIELD VALUES ARE NULL——某些字段空缺值都设为NULL。
对于字段长度和分割符不确定且准备用作外部表文件,可以使用UltraEdit、Editplus等来进行分析测试,如果文件较大,则需要考虑将文件分割成小文件并从中提取数据进行测试。

外部表对错误的处理 

REJECT LIMIT UNLIMITED
在创建外部表时最后加入LIMIT子句,表示可以允许错误的发生个数。默认值为零。设定为UNLIMITED则错误不受限制
BADFILE和NOBADFILE子句
用于指定将捕获到的转换错误存放到哪个文件。如果指定了NOBADFILE则表示忽略转换期间的错误
如果未指定该参数,则系统自动在源目录下生成与外部表同名的.BAD文件BADFILE记录本次操作的结果,下次将会被覆盖 LOGFILE和NOLOGFILE子句
同样在access parameters中加入LOGFILE 'LOG_FILE.log'子句,则所有Oracle的错误信息放入'LOG_FILE.log'中
而NOLOGFILE子句则表示不记录错误信息到log中,如忽略该子句,系统自动在源目录下生成与外部表同名的.LOG文件
注意以下几个常见的问题
1.外部表经常遇到BUFFER不足的情况,因此尽可能的增大READSIZE
2.换行符不对产生的问题。在不同的操作系统中换行符的表示方法不一样,碰到错误日志提示如是换行符问题,可以使用
UltraEdit打开,直接看十六进制
3.特定行报错时,查看带有"BAD"的日志文件,其中保存了出错的数据,用记事本打开看看那里出错,是否存在于外部表定义相冲突

外部表的局限性 

1.SQLLDR可以指定多少提交一次,即ROWS=?, 外部表却没有,这对于大数据量的导入有些不方例。
2.sqlldr errors表示允许错误的行数,外部表用REJECT LIMIT UNLIMITED,这个功能上基本相同。
3.外部表的列不能指定为not nullable,这样就很难拒绝某列为空值的记录。
4.外部表不能使用continueif ,如果记录有换行的就比较难处理。

当sqlmap的--os-shell失效时:手把手教你搞定Oracle数据库的命令执行与提权 本文深入探讨了当sqlmap的`--os-shell`失效时,如何手动实现Oracle数据库的命令执行与提权。通过分析DBMS_SCHEDULER、Java存储过程和外部表三大核心路径,提供了从注入点到系统权限的完整攻击链,并详细介绍了版本限制与权限要求,帮助安全研究人员在自动化工具失效时仍能有效突破Oracle数据库的防御。 阅读详情

相关推荐

PostgreSQL FDW实战:5分钟搞定跨数据库查询(含MySQL/Oracle配置)

本文详细介绍了PostgreSQL FDW(Foreign Data Wrapper)技术的实战应用,帮助用户快速实现跨数据库查询。通过清晰的四步配置法,文章演示了如何连接MySQL和Oracle等异构数据库,并探讨了性能优化与文件FDW等高级应用场景,有效解决数据孤岛问题,提升数据分析效率。

pz8901234的博客 991

Oracle外部表详解(转载)

外部表创建主要注意创建目录访问权限问题、目录路径格式无空格等不相关字符,即必须是当前表访问用户可以访问;关于表中行数的限制问题,如果不加限制注意添加reject limit unlimited;表中数据格式与创建表时access parameters中的定义需保持同步,适当用skip=1外部表概述 外部表只能在Oracle 9i之后来使用。简单地说,外部表,是指不存在于数据...

426

Oracle数据库导入导出工具与建表SQL实战指南

Oracle数据库采用实例与数据库分离的架构设计,实例由SGA(系统全局区)和后台进程组成,数据库则包含数据文件、控制文件与重做日志。SGA中包括共享池、数据库缓冲区高速缓存和重做日志缓冲区,负责SQL解析、数据块缓存与事务日志暂存;PGA(程序全局区)则为每个会话提供私有内存空间,用于排序、哈希操作等。关键后台进程如PMON(进程恢复)、SMON(系统监控)、DBWn(数据写入)和LGWR(日志写入)协同保障数据库高可用性与崩溃恢复能力。-- 查询当前实例内存分配情况。

weixin_35995661的博客 1041

数据在SQLLDR的时候提示错误, 使用TRAILING NULLCOLS

数据在SQLLDR的时候提示错误 记录 2407: 被拒绝 - 表  XXX的列 XXX 出现错误。 在逻辑记录结束之前未找到列 1.sale.log文件

x252513的专栏 2万+

oracle sql 高级编程学习笔记(二十九)

DML错误日志使用语法一、实例演示1、创建错入日志表2、声明 log error子句2.1 不设置reject limit插入数据2.2 加入reject limit 再进行插入二 、使用DML错误记录注意事项三、当基表中含有不支持的数据类型列时,创建Errors表的正确语法 DML错误日志这个功能提供一个机制来使得你的一百万行数据插入不会仅仅由于几行数据有问题而失败。 这个特性在10gR2中引...

whandgdh的博客 1489

oracle外部表分割符空格符,Oracle外部表处理中文字符

外部表的文件中,若文件中的字段由ctrl+F来分割,由于ctrl+F分隔符在中文后面无法被识别,使得外部表导入出现问题,解决办法是在外部表的文件中,若文件中的字段由ctrl+F来分割,由于ctrl+F分隔符在中文后面无法被识别,使得外部表导入出现问题,解决办法是在 创建外部表的过程中加入:characterset 'AL32UTF8'例:drop table tablenamecreate ta...

weixin_39861498的博客 182

oracle外部表创建语法,Oracle外部表ORACLE_LOADER门类的创建语法详解

field_definitions ClauseThe field_definitionsclause names the fields in the datafile and specifies how to find them in records.If the field_definitionsclause is omitted, then:The fields are assumed to...

weixin_39957271的博客 599

Doris 数据库外部表-JDBC 外表实战:Oracle 数据无缝集成与联合查询

本文详细介绍了如何在Doris数据库中通过JDBC外部表功能,实现与Oracle数据库的无缝集成与联合查询。文章从环境准备、驱动配置入手,逐步讲解了创建外部资源和外部表的实战步骤,并深入探讨了联合查询、性能优化及常见问题排查,帮助用户构建零延迟、简化的数据分析链路,有效利用Doris的OLAP能力处理实时业务数据。

sun99的博客 693

Oracle数据库基础学习13-外部表

外部表是指存储在外部文件中的数据,Oracle可以通过创建外部表以只读的方式来查询文件数据的内容,这对于文件数据的分析非常有用,而且还可以轻松的将外部表的内容插入到数据库中 注意:Oracle只能处理位于Oracle服务器上的外部文件,它依赖于Oracle的目录对象和 ORACLE_LOADER 来加载外部文件中的数据 实际上创建外部表只是在数据字典中添加了外部表的元数据信息,并没有在数据库中为外部文件创建数据表。Oracle通过访问驱动程序来读取外部表中的数据。Oracle提供了两种访问驱动,默认使用

Hjchidaozhe的博客 632

外部表 External Table

定义 External tables access data in external sources as if it were in a table in the database. You can connect to the database and create metadata for the external table using DDL. The DDL for an external table consists of two parts: one part that desc...

Aluphamii 2232

Oracle 外部表

一. 官网对外部表的说明   Managing External Tables http://download.oracle.com/docs/cd/E11882_01/server.112/e17120/tables013.htm#ADMIN12896

小宝老豆的专栏 809

Oracle外部表ET(External Table)

外部表只能在Oracle 9i之后来使用。

一只蓝精灵 776

oracle外部表使用详解,详解Oracle外部表的一次维护(图文)

在做Oracle数据库的导出导入操作的时候,发现在将导出数据导入到新库过程中报告如下错误:在查看数据库中关于外部表的视图中相关信息:select * from dba_directoriesSelect * from select * from dba_external_tables发现EXP_USERID表存在而目录EX_DATA不存在了!正常的情况下是先创建一个目录在创建外部表,,现在是目录丢...

weixin_35987446的博客 324

管理外部表

关于外部表 Oracle数据库允许你以只读方式访问外部表的数据。外部表被定义为不驻留在数据库的表,而且,只要提供了访问驱动程序外部表支持任意格式。只要提供了描述外部表的元数据,Oracle数据库就...

congjiumi6955的博客 169

ORACLE_OCP之外部表

ORACLE_OCP之外部表 外部表是只读表,作为文件存储在Oracle数据库外部的操作系统上。 一、External Table(外部表):优点 数据可以直接从外部文件使用,也可以加载到另一个数据库中。 可以直接查询外部数据并与数据库中的表并行地将其联接,而无需先加载。 复杂查询的结果可以导入到外部文件。(需要使用ORACLE_DATAPUMP) 您可以合并来自不同来源的生成文件以进行加载。 二、用ORACLE_LOADER定义外部表 CREATE TABLE extab_employees

XiaoHG_CSDN的博客 171

利用PL/SQL Developer和ODBC实现Excel数据高效导入Oracle数据库

本文详细介绍了如何利用PL/SQL Developer工具结合ODBC驱动,实现将Excel数据高效、准确地导入Oracle数据库。文章从驱动配置、工具使用到核心的五步导入流程进行了逐步解析,并提供了处理大数据量、自动化脚本以及常见问题(如中文乱码、日期格式)的进阶解决方案,是数据库开发与数据分析人员提升数据搬运效率的实用指南。

metal的博客 462

oracle临时表与外部表,Oracle中的临时表、外部表和分区表

Oracle中的临时表、外部表和分区表临时表在Oracle中,临时表是“静态”的,它与普通的数据表一样只需要一次创建,其结构从创建到删除的整个期间都是有效的。相对于其他类型的表,临时表只有在用户实际向表中添加数据时,才会为其分配空间,并且分配的空间来自临时表空间。这就避免了与永久对象的数据争用存储空间。创建临时表的语法如下:CREATE GLOBAL TEMPORARY TABLE table_n...

weixin_29447621的博客 190
上一篇: Oracle数据库备份与恢复 -RMAN两种库增量备份的差别
下一篇: Oracle DB sql*loader例子
IMezZ
博客等级 码龄10年 116粉丝 64原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值