oracle外部表!!!

sqlldr是把数据加载到数据库中;外部表中的数据是基于操作系统文件的,真正的数据没有保存到数据库中,是在操作系统文件里面的。所以外部表里面的数据只可以select。外部表基本上可以替代sqlldr。但是在以下3种情况下,应该选择sqlldr而不是外部表:

1.必须通过网络加载数据,也就是说,输入文件不在数据库服务器上。

2.多个用户必须并发的使用相同的外部表来处理不同的输入文件。

3.必须使用LOB类型。外部表不支持LOG。

 

利用sqlldr的例子来生成外部表的脚本

[oracle@linux sqlldr]$ pwd
/u01/sqlldr
[oracle@linux sqlldr]$ cat demo1.ctl 
LOAD DATA
INFILE *
INTO TABLE DEPT
FIELDS TERMINATED BY ','
(DEPTNO,DNAME,LOC)
BEGINDATA
10,Sales,Virginia
20,Accounting,Virginia
30,Consulting,Virginia
40,Finance,Virginia
ABC,XYZ,Hello
[oracle@linux sqlldr]$ sqlldr ing/ing demo1.ctl external_table=generate_only

SQL*Loader: Release 10.2.0.4.0 - Production on 星期二 10月 4 21:59:06 2011

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

查看生成的log文件

[oracle@linux sqlldr]$ pwd
/u01/sqlldr
[oracle@linux sqlldr]$ cat demo1.log 

SQL*Loader: Release 10.2.0.4.0 - Production on 星期二 10月 4 21:59:06 2011

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

控制文件:      demo1.ctl
数据文件:      demo1.ctl
  错误文件:    demo1.bad
  废弃文件:    未作指定
 
(可废弃所有记录)

要加载的数: ALL
要跳过的数: 0
允许的错误: 50
继续:    未作指定
所用路径:       外部表

表 DEPT,已加载从每个逻辑记录
插入选项对此表 INSERT 生效

   列名                        位置      长度  中止 包装数据类型
------------------------------ ---------- ----- ---- ---- ---------------------
DEPTNO                              FIRST     *   ,       CHARACTER            
DNAME                                NEXT     *   ,       CHARACTER            
LOC                                  NEXT     *   ,       CHARACTER            



文件需要 CREATE DIRECTORY 语句
------------------------------------------------------------------------
CREATE DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000 AS '/u01/sqlldr'
--sqlldr连接到数据库,查询数据字典。没有找到合适的目录,就创建一个SYS_SQLLDR_XT_TMPDIR_00000目录。

用于外部表的 CREATE TABLE 语句:
------------------------------------------------------------------------
CREATE TABLE "SYS_SQLLDR_X_EXT_DEPT"      --创建一张表SYS_SQLLDR_X_EXT_DEPT
(
  "DEPTNO" NUMBER(10),
  "DNAME" VARCHAR2(20),
  "LOC" VARCHAR2(20)
)
ORGANIZATION external           --表明这不是一张普通表,而是一张外部表。
(
  TYPE oracle_loader            --加载数据的类型。另外还有一个10G才支持的ORACLE_DATAPUMP可以用来加载或卸载数据。
  DEFAULT DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000            --使用前面创建的目录SYS_SQLLDR_XT_TMPDIR_00000
  ACCESS PARAMETERS 
  (
    RECORDS DELIMITED BY NEWLINE CHARACTERSET ZHS16GBK    --记录默认也换行符结束。
    BADFILE 'SYS_SQLLDR_XT_TMPDIR_00000':'demo1.bad'      --在刚创建的目录中记录一个坏文件,无法加载的记录会记录到此文件中。
    LOGFILE 'demo1.log_xt'                                --日志文件。
    READSIZE 1048576                                      --加载数据的缓存区大小。1024*1024=1048576
    SKIP 6                                                --跳过前面6行不加载,因为前面6行是sqlldr控制文件的信息。
    FIELDS TERMINATED BY "," LDRTRIM                      --数据以逗号分隔,LDRTRIM表示去掉前后的空白字符。
    REJECT ROWS WITH ALL NULL FIELDS                      --外部表会在坏文件中记录全空的行,而不加载这些行。
    (
      "DEPTNO" CHAR(255)
        TERMINATED BY ",",
      "DNAME" CHAR(255)
        TERMINATED BY ",",
      "LOC" CHAR(255)
        TERMINATED BY ","
    )
  )
  location 
  (
    'demo1.ctl'        --告诉oracle所加载的文件的文件名。
  )
)REJECT LIMIT UNLIMITED


用于加载内部表的 INSERT 语句:
------------------------------------------------------------------------
INSERT /*+ append */ INTO DEPT   --用于从外部表本身直接加载数据。 
(
  DEPTNO,
  DNAME,
  LOC
)
SELECT 
  "DEPTNO",
  "DNAME",
  "LOC"
FROM "SYS_SQLLDR_X_EXT_DEPT"


用于清除由以前的语句创建的对象的语句:
------------------------------------------------------------------------
DROP TABLE "SYS_SQLLDR_X_EXT_DEPT"            --删除外部表。
DROP DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000     --删除目录。



从 星期二 10月 04 21:59:06 2011 开始运行
在 星期二 10月 04 21:59:06 2011 处运行结束

经过时间为: 00: 00: 00.14
CPU 时间为: 00: 00: 00.04

下面就执行生成的脚本

SQL> conn /as sysdba
已连接。
SQL> CREATE DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000 AS '/u01/sqlldr';

目录已创建。

SQL> grant read,write on directory SYS_SQLLDR_XT_TMPDIR_00000 to ing;

授权成功。

SQL> conn ing/ing
已连接。
SQL> CREATE TABLE "SYS_SQLLDR_X_EXT_DEPT" 
  2  (
  3    "DEPTNO" NUMBER(10),
  4    "DNAME" VARCHAR2(20),
  5    "LOC" VARCHAR2(20)
  6  )
  7  ORGANIZATION external 
  8  (
  9    TYPE oracle_loader
 10    DEFAULT DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
 11    ACCESS PARAMETERS 
 12    (
 13      RECORDS DELIMITED BY NEWLINE CHARACTERSET ZHS16GBK
    BADFILE 'SYS_SQLLDR_XT_TMPDIR_00000':'demo1.bad'
    LOGFILE 'demo1.log_xt'
    READSIZE 1048576
      "DEPTNO" CHAR(255)
    SKIP 6
    FIELDS TERMINATED BY "," LDRTRIM 
    REJECT ROWS WITH ALL NULL FIELDS 
    (
      "DEPTNO" CHAR(255)
        TERMINATED BY ",",
 23        "DNAME" CHAR(255)
 24          TERMINATED BY ",",
 25        "LOC" CHAR(255)
 26          TERMINATED BY ","
 27      )
 28    )
 29    location 
 30    (
 31      'demo1.ctl'
 32    )
 33  )REJECT LIMIT UNLIMITED;

表已创建。

查询外部表

SQL> select * from SYS_SQLLDR_X_EXT_DEPT;

    DEPTNO DNAME                LOC
---------- -------------------- --------------------
        10 Sales                Virginia
        20 Accounting           Virginia
        30 Consulting           Virginia
        40 Finance              Virginia

此时到目录下面去查看bad文件会发现存在一条记录,正是无法加载到数据库中的记录,因为ABC无法转换问数字。

[oracle@linux sqlldr]$ pwd
/u01/sqlldr
[oracle@linux sqlldr]$ ll | grep demo1
-rw-r--r-- 1 oracle oinstall   14 10-04 22:15 demo1.bad
-rw-r--r-- 1 oracle oinstall  187 10-04 21:58 demo1.ctl
-rw-r--r-- 1 oracle oinstall 2319 10-04 21:59 demo1.log
-rw-r--r-- 1 oracle oinstall  570 10-04 22:15 demo1.log_xt
[oracle@linux sqlldr]$ cat demo1.bad 
ABC,XYZ,Hello

使用外部表加载不同的文件

首先另行准备一个数据文件(故意空了6行,因为我们定义外部表的时候指定了SKIP 6嘛)

[oracle@linux sqlldr]$ pwd
/u01/sqlldr
[oracle@linux sqlldr]$ cat demo2.data 






50,Sales,Virginia
60,Accounting,Virginia
70,Consulting,Virginia
80,Finance,Virginia

然后执行命令

SQL> alter table SYS_SQLLDR_X_EXT_DEPT location('demo2.data');

表已更改。

SQL> select * from SYS_SQLLDR_X_EXT_DEPT;

    DEPTNO DNAME                LOC
---------- -------------------- --------------------
        50 Sales                Virginia
        60 Accounting           Virginia
        70 Consulting           Virginia
        80 Finance              Virginia

你可能感兴趣的:(oracle,sql,linux,table,character,newline)