sqlload是oracle提供的批量導入文件數據的工具
1、在導入先,先根據數據建表。
2、執行sqlldr命令
sqlldr userid=username/password control =*.tl --要在ctl文件的目錄下執行
3、編寫ctl文件
for example:
load data
infile 'F:\STUDY\6.1\CELLPORT_20161124143843_exp_1.csv' --加載的文件
infile 'F:\STUDY\6.1\CELLPORT_20161124143843_exp_2.csv' --加載的文件
into table cellport --目標表
when port_status='空閑' --可以設置條件篩選數據
FIELDS TERMINATED BY ',' --設置分隔符,這里分隔符石,
OPTIONALLY ENCLOSED BY '"' --設置結束符,也可以不設置,除非數據很工整,否則最好設置
TRAILING NULLCOLS --設置空數據也,加載。
( --下面是表的字段,對每個字段還可以使用sql函數,進行一些計算或者格式轉換等等,
city,
house_name "upper(:house_name)", --使用函數
houes_type,
house_jd,
houese_wd,
eq_name,
eq_range,
eq_location,
eq_fgb,
eq_port,
port_status,
port_type,
OLT,
OLT_PON ,
NUMBER_209 , --
DL_TIMESTAMP date 'yyyy-mm-dd hh24:mi:ss' --時間轉換
)
參考資料http://www.cnblogs.com/CodingArt/articles/1624736.html
1.什么是*.csv,如何得到?
里面存放的是數據表.每行代表數據庫表格的一行,
每行中,每兩個數據中間由逗號","分割.
*.csv可以通過"將excel文件另存為*.csv"得到.
2.如何將*.csv格式的數據導入oracle數據庫?
舉例來說:
test.csv文件中存放以下數據.
a1,b1
a2,b2
存放路徑為:
d:\test.csv
准備將其存放到oracle數據庫中.
a.首先,則需要新建表(欄位數量和類型要和需要導入的一致)
create table test(A char,B char);
b.新建test.ctl文件
用記事本編輯寫入:
load data
infile ‘d:\test.csv’
into table “test”
fields terminated by ‘,’
(A,B)
c.打開cmd命令行界面
輸入:
sqlldr userid=user/password@database control=d:\test.ctl log=d:\test.log
回車
user/password@database:為賬號和密碼以及數據庫名稱.
以上的介紹比較簡單.
http://www.blogjava.net/Unmi/archive/2009/01/05/249956.html
里面的介紹比較詳細,我轉到這里:
在 Oracle 數據庫中,我們通常在不同數據庫的表間記錄進行復制或遷移時會用以下幾種方法:
1. A 表的記錄導出為一條條分號隔開的 insert 語句,然后執行插入到 B 表中
2. 建立數據庫間的 dblink,然后用 create table B as select * from A@dblink where ...,或 insert into B select * from A@dblink where ...
3. exp A 表,再 imp 到 B 表,exp 時可加查詢條件
4. 程序實現 select from A ..,然后 insert into B ...,也要分批提交
5. 再就是本篇要說到的 Sql Loader(sqlldr) 來導入數據,效果比起逐條 insert 來很明顯
第 1 種方法在記錄多時是個噩夢,需三五百條的分批提交,否則客戶端會死掉,而且導入過程很慢。如果要不產生 REDO 來提高 insert into 的性能,就要下面那樣做:
2
3 insert /* +APPEND */ into B(c1,c2) values(x,xx);
4 insert /* +APPEND */ into B select * from A@dblink where .....;
5
好啦,前面簡述了 Oracle 中數據導入導出的各種方法,我想一定還有更高明的。下面重點講講 Oracle 的 Sql Loader (sqlldr) 的用法。
在命令行下執行 Oracle 的 sqlldr 命令,可以看到它的詳細參數說明,要着重關注以下幾個參數:
userid -- Oracle 的 username/password[@servicename]
control -- 控制文件,可能包含表的數據
-------------------------------------------------------------------------------------------------------
log -- 記錄導入時的日志文件,默認為 控制文件(去除擴展名).log
bad -- 壞數據文件,默認為 控制文件(去除擴展名).bad
data -- 數據文件,一般在控制文件中指定。用參數控制文件中不指定數據文件更適於自動操作
errors -- 允許的錯誤記錄數,可以用他來控制一條記錄都不能錯
rows -- 多少條記錄提交一次,默認為 64
skip -- 跳過的行數,比如導出的數據文件前面幾行是表頭或其他描述
還有更多的 sqlldr 的參數說明請參考:sql loader的用法。
用例子來演示 sqlldr 的使用,有兩種使用方法:
1. 只使用一個控制文件,在這個控制文件中包含數據
2. 使用一個控制文件(作為模板) 和一個數據文件
一般為了利於模板和數據的分離,以及程序的不同分工會使用第二種方式,所以先來看這種用法。數據文件可以是 CSV 文件或者以其他分割符分隔的,數據文件可以用 PL/SQL Developer 或者 Toad 導出,也可以用 SQL *Plus 的 spool 格式化產出,或是 UTL_FILE 包生成。另外,用 Toad 還能直接生成包含數據的控制文件。
首先,假定有這么一個表 users,並插入五條記錄:
insert into users values(2,NULL,5,to_date('2008-10-15','YYYY-MM-DD'));
insert into users values(3,'隔葉黃鶯',8,to_date('2009-01-02','YYYY-MM-DD'));
insert into users values(4,'Kypfos',NULL,NULL);
insert into users values(5,'不知秋',1,to_date('2008-12-23','YYYY-MM-DD'));
1) 建立數據文件,我們這里用 PL/SQL Developer 導出表 users 的記錄為 users_data.csv 文件,內容如下:
"1","1","Unmi","3","2009-1-5 20:34:44"
"2","2","","5","2008-10-15"
"3","3","隔葉黃鶯","8","2009-1-2"
"4","4","Kypfos","",""
"5","5","不知秋","1","2008-12-23"
LOAD DATA
INFILE * -- 因為數據同控制文件在一起,所以用 * 表示
append -- 這里用了 append 來操作,在表 users 中附加記錄
INTO TABLE users
when LOGIN_TIMES<>'8' -- 還可以用 when 子句選擇導入符合條件的記錄
Fields terminated by ","
trailing nullcols
(
virtual_column FILLER, --跳過由 PL/SQL Developer 生成的第一列序號
user_id "user_seq.nextval", --這一列直接取序列的下一值,而不用數據中提供的值
user_name "'Hi '||upper(:user_name)",--,還能用SQL函數或運算對數據進行加工處理
login_times terminated by ",", NULLIF(login_times='NULL') --可為列單獨指定分隔符
last_login DATE "YYYY-MM-DD HH24:MI:SS" NULLIF (last_login="NULL") -- 當字段為"NULL"時就是 NULL
)
BEGINDATA --數據從這里開始
,USER_ID,USER_NAME,LOGIN_TIMES,LAST_LOGIN
1,1,Unmi,3,2009-1-5 20:34
2,2,Fantasia,5,2008-10-15
3,3,隔葉黃鶯,8,2009-1-2
4,4,Kypfos,NULL,NULL
5,5,不知秋,1,2008-12-23
2) 執行一樣的命令:
sqlldr dbuser/dbpass@dbservice control=users.ctl
比如,在控制台會顯示這樣的信息:
C:\>sqlldr dbuser/dbpass@dbservice control=users.ctl
SQL*Loader: Release 9.2.0.1.0 - Production on 星期三 1月 7 22:26:25 2009
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
達到提交點,邏輯記錄計數4
達到提交點,邏輯記錄計數5
上面的控制文件包含的內容比較復雜(演示目的),請根據注釋理解每個參數的意義。還能由此發掘更多用法。
最后說下有關 SQL *Loader 的性能與並發操作
1) ROWS 的默認值為 64,你可以根據實際指定更合適的 ROWS 參數來指定每次提交記錄數。(體驗過在 PL/SQL Developer 中一次執行幾條條以上的 insert 語句的情形嗎?)
2)常規導入可以通過使用 INSERT語句來導入數據。Direct導入可以跳過數據庫的相關邏輯(DIRECT=TRUE),而直接將數據導入到數據文件中,可以提高導入數據的性能。當然,在很多情況下,不能使用此參數(如果主鍵重復的話會使索引的狀態變成UNUSABLE!)。
3) 通過指定 UNRECOVERABLE選項,可以關閉數據庫的日志(是否要 alter table table1 nologging 呢?)。這個選項只能和 direct 一起使用。
4) 對於超大數據文件的導入就要用並發操作了,即同時運行多個導入任務.
sqlldr userid=/ control=result1.ctl direct=true parallel=true
sqlldr userid=/ control=result2.ctl direct=true parallel=true
sqlldr userid=/ control=result2.ctl direct=true parallel=true
當加載大量數據時(大約超過10GB),最好抑制日志的產生:
SQL>ALTER TABLE RESULTXT nologging;
這樣不產生REDO LOG,可以提高效率。然后在 CONTROL 文件中 load data 上面加一行:unrecoverable, 此選項必須要與DIRECT共同應用。
在並發操作時,ORACLE聲稱可以達到每小時處理100GB數據的能力!其實,估計能到 1-10G 就算不錯了,開始可用結構 相同的文件,但只有少量數據,成功后開始加載大量數據,這樣可以避免時間的浪費。
參考資料:http://blog.csdn.net/dws2004/article/details/6956961
SQLLDR keyword=value [,keyword=value,...]
有效的關鍵字:
userid -- Oracle 用戶名/口令
control -- 控制文件名
log -- 日志文件名
bad -- 錯誤文件名
data -- 數據文件名
discard -- 廢棄文件名
discardmax -- 允許廢棄的文件的數目 (全部默認)
skip -- 要跳過的邏輯記錄的數目 (默認 0)
load -- 要加載的邏輯記錄的數目 (全部默認)
errors -- 允許的錯誤的數目 (默認 50) 如果不指定,達到錯誤上限自動停止,肯定是沒有完全導入
rows -- 常規路徑綁定數組中或直接路徑保存數據間的行數(默認: 常規路徑 64, 所有直接路徑)
bindsize -- 常規路徑綁定數組的大小 (以字節計) (默認 256000)
silent -- 運行過程中隱藏消息 (標題,反饋,錯誤,廢棄,分區)
direct -- 使用直接路徑 (默認 FALSE)
parfile -- 參數文件: 包含參數說明的文件的名稱
parallel -- 執行並行加載 (默認 FALSE)
file -- 要從以下對象中分配區的文件
skip_unusable_indexes -- 不允許/允許使用無用的索引或索引分區 (默認 FALSE)
skip_index_maintenance -- 沒有維護索引, 將受到影響的索引標記為無用 (默認 FALSE)
commit_discontinued -- 提交加載中斷時已加載的行 (默認 FALSE)
readsize -- 讀取緩沖區的大小 (默認 1048576)
external_table -- 使用外部表進行加載; NOT_USED, GENERATE_ONLY, EXECUTE (默認 NO
T_USED)
columnarrayrows -- 直接路徑列數組的行數 (默認 5000)
streamsize -- 直接路徑流緩沖區的大小 (以字節計) (默認 256000)
multithreading -- 在直接路徑中使用多線程
resumable -- 啟用或禁用當前的可恢復會話 (默認 FALSE)
resumable_name -- 有助於標識可恢復語句的文本字符串
resumable_timeout -- RESUMABLE 的等待時間 (以秒計) (默認 7200)
date_cache -- 日期轉換高速緩存的大小 (以條目計) (默認 1000)
PLEASE NOTE: 命令行參數可以由位置或關鍵字指定。前者的例子是 'sqlload scott/tiger foo';后一種情況的一個示例是 'sqlldr control=foo userid=scott/tiger'.位置指定參數的時間必須早於, 但不可遲於由關鍵字指定的參數。例如, 允許 'sqlldr scott/tiger control=foo logfile=log', 但是不允許 'sqlldr scott/tiger control=foo log', 即使參數 'log' 的位置正確。
實踐
LOAD DATA
INFILE 'result/stat-20100821-detail.txt'
replace
into table LOGDETAILS_20100821 -- insert append replace
FIELDS TERMINATED BY ' |+-s| ' --字段分割符號
TRAILING NULLCOLS --允許匹配不到的字段
(
ID RECNUM , --RECNUM屬性來實現id的自增 如果入庫方式是追加一定要使用序列 COUNTERINFO_SEQ.nextval
IP ,
HITTIME "to_date(:HITTIME, 'YYYY-MM-DD HH24:Mi:SS')",
URL ,
STATUS ,
SIZES ,
URL_SOURCE char(1024),
TOOLS char(1024),
SERVERINFO ,
SYSTEM_ID ,
SOURCETYPE_ID ,
SERVERSOURCE
)
整理問題
value used for ROWS parameter changed from 64 to 58
Record 49305: Rejected - Error on table LOGDETAILS_20100822, column SERVERSOURCE.
ORA-12899: value too large for column "LOGANALYSER"."LOGDETAILS_20100822"."SERVERSOURCE" (actual: 71, maximum: 50)
Record 49561: Rejected - Error on table LOGDETAILS_20100822, column SERVERSOURCE.--字段長度
ORA-12899: value too large for column "LOGANALYSER"."LOGDETAILS_20100822"."SERVERSOURCE" (actual: 71, maximum: 50)
ORA-01653: unable to extend table LOGANALYSER.LOGDETAILS_20100822 by 128 in tablespace TBS_LOGANALYSER --表空間配額不足
SQL*Loader-605: Non-data dependent ORACLE error occurred -- load discontinued.
特殊說明
使用SQLLOAD導入數據時四種裝入方式導入數據
APPEND //原先的表有數據就加在后面
INSERT // 裝載空表,如果原先的表有數據SQLLOADER會停止默認值
REPLACE // 原先的表有數據 原先的數據會全部刪除
TRUNCATE // 指定的內容和REPLACE的相同會用TRUNCATE語句刪除
使用SQLLOAD導入數據時 不導入從文件頭開始的指定行數據:sqlldr
time_loaded "to_char(SYSDATE, 'HH24:MI')",
data1 POSITION(1:5) ":data1/100",
data2 POSITION(6:15) "upper(:data2)",
data3 POSITION(16:22)"to_date(:data3, 'YYMMDD')" --還可以DATE DD/MM/YYYY
使用SQL*LOAD一次導入多個文件到同一個表:
LOAD DATA
INFILE file1.dat
INFILE file2.dat
INFILE file3.dat
APPEND
INTO TABLE emp
( empno POSITION(1:4) INTEGER EXTERNAL, --字段長度確定時,使用POSITION定位
ename POSITION(6:15) CHAR,
deptno POSITION(17:18) CHAR,
mgr POSITION(20:23) INTEGER EXTERNAL
)
使用when條件指定SQL*LOAD將一個文件導入不同的表: INTO TABLE tablename WHEN filed = '條件'
使用SQL*LOAD有選擇性的導入數據到一個或多個表中:
注:
SQL*LOAD不允許在when語句中使用OR...只能使用AND
(01) 表示數據文件中的第一個字符
(30:37) 表示數據文件中第30-37個字符
LOAD DATA
INFILE 'mydata.dat' BADFILE 'mydata.bad' DISCARDFILE 'mydata.dis'
APPEND
INTO TABLE my_selective_table
WHEN (01) <> 'H' and (01) <> 'T'
(
region CONSTANT '31',
service_key POSITION(01:11) INTEGER EXTERNAL,
call_b_no POSITION(12:29) CHAR
)
INTO TABLE my_selective_table
WHEN (30:37) = '20031217'
(
region CONSTANT '31',
service_key POSITION(01:11) INTEGER EXTERNAL,
call_b_no POSITION(12:29) CHAR
)
使用SQL*LOAD導入數據時,通過在字段上使用關鍵字過濾數據文件中的指定列: field2 FILLER
使用SQL*LOAD導入數據時,通過使用關鍵字表示把多行記錄合並成一行:CONCATENATE 3
使用SQL*LOAD導入LOB等大對象:
CREATE TABLE image_table (
image_id NUMBER(5),
file_name VARCHAR2(30),
image_data BLOB);
LOAD DATA
INFILE *
INTO TABLE image_table
REPLACE
FIELDS TERMINATED BY ','
(
image_id INTEGER(5),
file_name CHAR(30),
image_data LOBFILE (file_name) TERMINATED BY EOF
)
BEGINDATA
001,image1.gif
002,image2.jpg
003,image3.jpg