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 control=d:/test.ctl log=d:/test.log
回車
: 爲賬號和密碼以及數據庫名稱.
以上的介紹比較簡單.
http://www.blogjava.net/Unmi/archive/2009/01/05/249956.html
裏面的介紹比較詳細,我轉到這裏:
在 Oracle 數據庫中,我們通常在不同數據庫的表間記錄進行復制或遷移時會用以下幾種方法:
1. A 表的記錄導出爲一條條分號隔開的 insert 語句,然後執行插入到 B 表中
2. 建立數據庫間的 dblink,然後用 create table B as select * from where ...,或 insert into B select * from 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,並插入五條記錄:
2 user_id number, --用戶 ID
3 user_name varchar2(50), --用戶名
4 login_times number, --登陸次數
5 last_login date --最後登錄日期
6 )
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 "users_data.csv" --指定外部數據文件,可以寫多個 INFILE "another_data_file.csv" 指定多個數據文件
--這裏還可以使用 BADFILE、DISCARDFILE 來指定壞數據和丟棄數據的文件,
truncate --操作類型,用 truncate table 來清除表中原有記錄
INTO TABLE users -- 要插入記錄的表
Fields terminated by "," -- 數據中每行記錄用 "," 分隔
Optionally enclosed by '"' -- 數據中每個字段用 '"' 框起,比如字段中有 "," 分隔符時
trailing nullcols --表的字段沒有對應的值時允許爲空
(
virtual_column FILLER, --這是一個虛擬字段,用來跳過由 PL/SQL Developer 生成的第一列序號
user_id number, --字段可以指定類型,否則認爲是 CHARACTER 類型, log 文件中有顯示
user_name,
login_times,
last_login DATE "YYYY-MM-DD HH24:MI:SS" -- 指定接受日期的格式,相當用 to_date() 函數轉換
)
說明:在操作類型 truncate 位置可用以下中的一值:
1) insert --爲缺省方式,在數據裝載開始時要求表爲空
2) append --在表中追加新記錄
3) replace --刪除舊記錄(用 delete from table 語句),替換成新裝載的記錄
4) truncate --刪除舊記錄(用 truncate table 語句),替換成新裝載的記錄
3) 執行命令:
sqlldr control=users.ctl
在 dbservice 指示的數據庫的表 users 中記錄就和數據文件中的一樣了。
執行完 sqlldr 後希望能留意一下生成的幾個文件,如 users.log 日誌文件、users.bad 壞數據文件等。特別是要看看日誌文件,從中可讓你更好的理解 Sql Loader,裏面有對控制文件的解析、列出每個字段的類型、加載記錄的統計、出錯原因等信息。
第一種方式,只使用一個控制文件在這個控制文件中包含數據
1) 把 users_data.cvs 中的內容補到 users.ctl 中,並以 BEGINDATA 連接,還要把 INFILE "users_data.csv" 改爲 INFILE *。同時爲了更大化的說明問題,把數據處理了一下。此時,完整的 users.ctl 文件內容是:
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 control=users.ctl
比如,在控制檯會顯示這樣的信息:
C:/>sqlldr 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 就算不錯了,開始可用結構 相同的文件,但只有少量數據,成功後開始加載大量數據,這樣可以避免時間的浪費。
示例:
--------------------
批處理文件:
aa.bat:
@echo off
echo 請輸入用戶名:
set /p user_name=
echo 請輸入密碼:
set /p user_pwd=
echo 請輸入連接串(TNS_NAME):
set /p user_tnsname=
sqlldr %user_name%/%user_pwd%@%user_tnsname% table_name.ctl skip=1
pause
------------------
table_name.ctl :
LOAD DATA
INFILE 'table_name.csv'
BADFILE 'data1.bad'
DISCARDFILE 'data1.dsc'
DISCARDMAX 10
APPEND
INTO TABLE "table_name"
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
TRAILING NULLCOLS
(
VERSION_ID,
PAGE_ID,
VERSION_NUM,
VERSION_DESC,
VERSION_CODE char(1000000),
VERSION_STATE,
CREATE_PERSN,
CREATE_DATE DATE "YYYY-MM-DD HH24:MI:SS",
TEMPLATE_ID,
PAGE_CONT char(1000000),
PAGE_SWF_FTP_PATH,
PAGE_CODE_FTP_PATH
)