DIRECT PATH LOAD : 從TXT檔案直接匯入資料庫
ORACLE可以從純文字檔直接匯入到資料表,稱之為 DIRECT PATH LOAD ,有別於傳統的匯入方式 (CONVENTIONAL),一定使用INSERT指令,一定有COMMIT。
- 傳統的INSERT,會使用Database Buffer Cache,且資料寫入在HIGH WATER MARK範圍之內,DIRECT PATH LOAD跳過 DATABASE BUFFER CACHE,且寫入DATAFILE的時候,
從HIGH WATER MARK之後插入,稱之為 DATA SAVE
- 傳統方式需要COMMIT, DIRECT PATH LOAD不用COMMIT
- 傳統方式會受限於Referential Integrity Constraints ,且TRIGGER可被觸發。 DIRECT PATH LOAD必須停掉Referential Integrity Constraints,且TRIGGER不會觸發
- DIRECT PATH LOAD時,TABLE會被LOCK不允許DML
- DIRECT PATH LOAD插入資料時,只允許UNIQUE、PRIMARY KEY和NOT NULL 三個Constraints
- DIRECT PATH LOAD 不能被用在CLUSTER TABLE
DIRECT PATH LOAD 需要下列條件或準備
- INPUT DATA FILES : 純文字檔,通常以逗點來分隔欄位
- CONTROL FILE : 跟資料庫的 CONTROLFILE沒有關係,是一個純文字檔,描述匯入的程序和指令
- LOG FILES : 寫在前述 CONTROL FILE,紀錄匯入紀錄
- BAD FILES : 寫在前述 CONTROL FILE,已經讀出,但被SQL LOADER拒絕不能匯入的資料寫入此,例如因為格式不合
- REJECT FILES : 寫在前述 CONTROL FILE,因違反表格限制條件而不能匯入的資料寫入此
- 匯入前,必須在資料庫先將TABLE建立好
在DB先建立下列表格
CREATE TABLE HR.DEPTS
(
DEPTNO NUMBER(2) NOT NULL,
DNAME VARCHAR2(14) ,
LOC VARCHAR2(13)
);
在主機中建立下列純文字檔,命名為 depts.txt
60,CONSULTING,TORONTO
70,HR,OXFORD
80,EDUCATION
在主機中建立下列 CONTROL FILE指令檔,命名為 DEPTS.CTL
load data
infile 'depts.txt' --匯入的檔案
badfile 'depts.bad' --壞掉的檔案放此
discardfile 'depts.dsc' --被拒絕匯入的放此
append --以插入方式匯入到WATER MARK後面
into table depts --插入新增到在資料庫中建好的表格
fields terminated by ',' --欄位,以逗點分隔
trailing nullcols --空白的欄位,以NULL填寫
(deptno integer external(2), --欄位的定義
dname,
loc)
指令檔建好以後,在命令列下執行下列命令
[oracle@db01 plsql]$ sqlldr userid=hr/XXXXX control=DEPTS.CTL direct=true
SQL*Loader: Release 11.2.0.1.0 - Production on Thu Jan 18 05:23:56 2018
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Load completed - logical record count 3.
匯入完成以後,看看紀錄檔產生些什麼
[oracle@db01 plsql]$ cat DEPTS.log
SQL*Loader: Release 11.2.0.1.0 - Production on Thu Jan 18 05:23:56 2018
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Control File: DEPTS.CTL
Data File: depts.txt
Bad File: depts.bad
Discard File: depts.dsc
(Allow all discards)
Number to load: ALL
Number to skip: 0
Errors allowed: 50
Continuation: none specified
Path used: Direct
Table DEPTS, loaded from every logical record.
Insert option in effect for this table: APPEND
TRAILING NULLCOLS option in effect
Column Name Position Len Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
DEPTNO FIRST 2 , CHARACTER
DNAME NEXT * , CHARACTER
LOC NEXT * , CHARACTER
Table DEPTS:
3 Rows successfully loaded.
0 Rows not loaded due to data errors.
0 Rows not loaded because all WHEN clauses were failed.
0 Rows not loaded because all fields were null.
Bind array size not used in direct path.
Column array rows : 5000
Stream buffer bytes: 256000
Read buffer bytes: 1048576
Total logical records skipped: 0
Total logical records read: 3
Total logical records rejected: 0
Total logical records discarded: 0
Total stream buffers loaded by SQL*Loader main thread: 1
Total stream buffers loaded by SQL*Loader load thread: 0
Run began on Thu Jan 18 05:23:56 2018
Run ended on Thu Jan 18 05:23:58 2018
Elapsed time was: 00:00:01.15
CPU time was: 00:00:00.01
插入後的表格可看到結果如下
使用SQL*LOADER : 從TXT檔案直接匯入資料庫
使用 SQL*LOADER 需要下列條件或準備
- DIRECTORY物件 : 需存在建好的目錄物件,並且賦予讀寫權限
- INPUT DATA FILES : 純文字檔,通常以逗點來分隔欄位,需放在上述目錄物件指向之位置
- SQL FILES : 在TOAD中執行即可
在上述目錄的位置放置要匯入的純文字檔,例如,在/home/oracle/bkup 目錄下有兩個純文字檔 empxt1.dat 和 empxt2.dat,如下圖所示
例如,文字檔有四個欄位
123,Dah-Lih,Jeng,01-jan-2018
124,Mary,Jeng,02-may-2017
125,Ezekiel,Jeng,12-feb-2015
然後,透過下列SQL將文字匯入到資料庫中
create table extab_employees
( employee_id number(4),
first_name varchar2(20),
last_name varchar2(25),
hire_date date)
organization external
( type ORACLE_LOADER DEFAULT DIRECTORY EXT_DIR
ACCESS PARAMETERS
( records delimited by newline
badfile EXT_DIR:'empxt%a_%p.bad'
logfile EXT_DIR:'empxt%a_%p.log'
fields terminated by ','
missing field values are null
( employee_id, first_name, last_name,
hire_date char date_format date mask "dd-mon-yyyy"))
LOCATION ('empxt1.dat','empxt2.dat'))
parallel reject limit unlimited;
匯入後查詢可確認是否成功
External Tables : 從資料庫直接讀取主機上以純文字建立之表格
External Tables 的使用是在有需要從主機的純文字檔讀取資料,可是又不想把該文字檔匯入成表格的時候,可以改用此方法,讀取外部的表格。該表格建立以後,可以用以查詢,使用於JOIN,或用以建立VIEWS或子查詢,但是不可以進行任何DML。
External Tables 的建立只要透過create table,配合 關鍵字 organization external ,就可以達成,但需要下列條件或準備
- 建立DIRECTORY : 以SYSDBA登入,建立DIRECTORY以後,將讀寫權限ASSIGN給該TABLE的USER
- 將純文字檔放至該DIRECTORY指定之目錄。
- 建立 External Tables
先建立DIRECTORY (以SYSDBA)
CREATE OR REPLACE DIRECTORY
EXT_DIR AS
'/home/oracle/bkup';
GRANT READ, WRITE ON DIRECTORY EXT_DIR TO HR;
把剛才的純文字檔複製到該目錄去
[oracle@db01 plsql]$ cp depts.txt ../bkup/
複製完成後,使用TOAD或是SQLPLUS執行下列SQL,建立外部表格
create table new_dept
( deptno number(2),
dname varchar2(14),
loc varchar2(13))
organization external (
type oracle_loader
default directory ext_dir
access parameters
( records delimited by newline
badfile 'depts.bad'
discardfile 'depts.dsc'
logfile 'depts.log'
fields terminated by ','
missing field values are null)
location ('depts.txt'));
該語法跟前述 DIRECT PATH LOAD的CONTROL FILE非常接近,然後透過TOAD可以看到該表格已經建立成功
當然,上述的CONTROL FILE稍嫌複雜,也可反向操作,將前述使用SQL LOADER匯入表格的命令,改為讓它產生EXTERNAL TABLE的SQL
[oracle@db01 plsql]$ sqlldr userid=hr/xxxx control=DEPTS.CTL external_table=generate_only
SQL*Loader: Release 11.2.0.1.0 - Production on Thu Jan 18 08:07:03 2018
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
執行完畢,去檢查所產生的
LOG檔,該檔案有完整的步驟:建立目錄、執行SQL產生EXTERNAL TABLES ,但是在進行下一步前,使用編輯器將一些該檔案內的路徑、檔案名稱、TABLE名稱等資訊換成正確的路徑和名稱,同時先將文字檔放在目錄所指向的路徑上,最後再去執行該檔案的SQL就可順利建立一個EXTERNAL TABLE。
External Tables 支援以下的特性
- 欄位加密 (Encrypted Columns)
- Clustered Tables
- Different partition at unload and load time, and others (see Notes)
與External Table 有關的資料字典
External Tables 有關的資料字典如下
- (DBA/ALL/USER)_EXTERNAL_TABLES
- (DBA/ALL/USER)_EXTERNAL_LOCATIONS
- (DBA/ALL/USER)_TABLES, and others