SQL*LOADER是ORACLE的数据加载工具,通常用来将操作系统文件迁移到ORACLE数据库中。SQL*LOADER是大型数据仓库选择使用的加载方法,因为它提供了最快速的途径(DIRECT,PARALLEL)。SQL*LOADER只能导入纯文本。
现在,我们抛开其理论不谈,用实例来使您快速掌握SQL*LOADER的使用方法。
在NT下,SQL*LOADER的命令为SQLLDR,在UNIX下一般为sqlldr/sqlload。 如执行:d:\\oracle>sqlldr
SQL*Loader: Release 8.1.6.0.0 - Production on 星期二 1月 8 11:06:42 2002 (c) Copyright 1999 Oracle Corporation. All rights reserved.
SQLLOAD用法: SQLLOAD 关键字 = 值 [,keyword=value,...] 有效的关键字:
userid -- ORACLE username/password control -- Control file name
log -- Log file name (日志文件,记录sqlload过程中产生的日志) bad -- Bad file name data -- Data file name
discard -- Discard file name (废弃文件)
discardmax -- Number of discards to allow (全部默认) skip -- Number of logical records to skip (默认0) load -- Number of logical records to load (全部默认) errors -- Number of errors to allow (默认50)
rows -- Number of rows in conventional path bind array or between direct path data saves
(默认: 常规路径 64, 所有直接路径)
bindsize -- Size of conventional path bind array in bytes (默认65536) silent -- Suppress messages during run (header,feedback,errors,discards,partitions) direct -- use direct path (默认FALSE)
parfile -- parameter file: name of file that contains parameter specifications parallel -- do parallel load (默认FALSE)
file -- File to allocate extents from
skip_unusable_indexes -- disallow/allow unusable indexes or index partitions (默认FALSE) skip_index_maintenance -- do not maintain indexes, mark affected indexes as unusable
(默认FALSE)
commit_discontinued -- commit loaded rows when load is discontinued (默认FALSE) readsize -- Size of Read buffer (默认1048576) 说明: 命令行参数可以由位置或关键字指定。
命令行参数由位置指定,例如 :sqlload scott/tiger foo
命令行参数由关键字指定,例如:sqlload control=foo userid=scott/tiger 通过位置指定的参数必须要在关键字指定的参数之前。例如,
'SQLLOAD SCott/tiger control=foo logfile=log', 但'不允许 sqlload scott/tiger control=foo log',即使log的位置顺序是正确的也不可以。
现在开始以实例来讲解其用法:
一、已存在数据源result.csv,欲导入ORACLE中FANCY用户下。 result.csv内容:
1,默任Web站点,192.168.2.254:80:,RUNNING 2,other,192.168.2.254:80:test.com,STOPPED
3,third,192.168.2.254:81:thirdabc.com,RUNNING
从中,我们看到3行数据,每行4列,分别以逗号分隔,为变长字符串。
二、制定控制文件result.ctl result.ctl内容: load data
infile 'result.csv'
into table resultxt
(resultid char terminated by ',', website char terminated by ',', ipport char terminated by ',', status char terminated by whitespace) 说明:
infile 指数据源文件
省略了默认的discardfile result.dsc和badfile result.bad
into table resultxt 默认是INSERT,也可以into table resultxt APPEND为追加方式,或 REPLACE,或truncate(truncate into table 表名 partition 分区名)
terminated by ',' 指用逗号分隔;当所有列的分隔符相同时,可以统一说明, fields terminated by ',' (分割符都为逗号) terminated by whitespace 结尾以空白分隔
三、此时我们执行加载:
D:\\>sqlldr userid=fancy/testpass control=result.ctl log=resulthis.out
SQL*Loader: Release 8.1.6.0.0 - Production on 星期二 1月 8 10:25:42 2002
(c) Copyright 1999 Oracle Corporation. All rights reserved.
SQL*Loader-941: 在描述表RESULTXT时出现错误 ORA-04043: 对象 RESULTXT 不存在
提示出错,因为数据库没有对应的表;创建该表:
create table resultxt (resultid varchar2(500),website varchar2(500), ipport varchar2(500),status varchar2(500))
四、重新执行加载
D:\\>sqlldr userid=fancy/k1i7l6l8 control=result.ctl log=resulthis.out
SQL*Loader: Release 8.1.6.0.0 - Production on 星期二 1月 8 10:31:57 2002
(c) Copyright 1999 Oracle Corporation. All rights reserved.
达到提交点,逻辑记录计数2(Commit point reached - logical record count 2) 达到提交点,逻辑记录计数3
已经成功,我们可以通过日志文件来分析其过程;resulthis.out内容如下: SQL*Loader: Release 8.1.6.0.0 - Production on 星期二 1月 8 10:31:57 2002 (c) Copyright 1999 Oracle Corporation. All rights reserved.
控制文件(Control File): result.ctl 数据文件(Data File) : result.csv 错误文件(Bad File) : result.bad 废弃文件(Discard File): 未作指定
(可废弃所有记录(Allow all discards)) 装载数(Number to load): ALL 跳过数(Number to skip): 0
允许的错误(Errors allowed): 50
绑定数组(Bind array): 64 行,最大 65536 字节 继续Continuation: 未作指定
所用路径(Path used): 常规
表RESULTXT 已载入从每个逻辑记录
(Table RESULTXT, partition P29_200706, loaded from every logical record.)
插入选项对此表INSERT生效 (Insert option in effect for this partition: TRUNCATE) 列名 位置 长度 中止 包装数据类型 (Column Name Position Len Term Encl Datatype)
------------------------------ ---------- ----- ---- ---- ------------------------------------------------------- RESULTID FIRST * , CHARACTER WEBSITE NEXT * , CHARACTER IPPORT NEXT * , CHARACTER STATUS NEXT * WHT CHARACTER
表RESULTXT:
3 行载入成功
由于数据错误, 0 行没有载入。
由于所有 WHEN 子句失败, 0 行没有载入。 由于所有字段都为空的, 0 行没有载入。 为结合数组分配的空间: 65016字节(63行) 除绑定数组外的内存空间分配: 0字节 跳过的逻辑记录总数: 0 读取的逻辑记录总数: 3 拒绝的逻辑记录总数: 0
废弃的逻辑记录总数: 0
从星期二 1月 08 10:31:57 2002开始运行 在星期二 1月 08 10:32:00 2002处运行结束 经过时间为 : 00: 00: 02.70 CPU 时间为: 00: 00: 00.10
五、并发操作
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就算不错了。
在程序的测试过程,可用结构相同的文件,但只有少量数据,成功后开始加载大量数据, 这样可以避免时间的浪费。
六、实例
文件中数据类型 -------数据库的数据类型 date---------―――--date
char--------―――---char,varchar integer―――----------number float--------------long 控制文件例子: LOAD DATA
INFILE 'stp.all'
INTO TABLE acct_tmp
fields terminated by ',' OPTIONALLY ENCLOSED BY ';' (
RADACCTID float external, ACCTSESSIONID CHAR(80), USERNAME CHAR(64), REALM CHAR(30),
NASIPADDRESS CHAR(34), NASPORTID CHAR(272), NASPORTTYPE CHAR(32),
ACCTSTARTTIME DATE(19) 'yyyymmdd hh24:mi:ss', ACCTSTOPTIME DATE(19) 'yyyymmdd hh24:mi:ss', ACCTSESSIONTIME float external, ACCTAUTHENTIC CHAR(32), ACCTINPUTOCTETS float external, ACCTOUTPUTOCTETS float external, CALLINGSTATIONID CHAR(64), ACCTTERMINATECAUSE CHAR(32), SERVICETYPE float external, FRAMEDPROTOCOL CHAR(32), FRAMEDIPADDRESS CHAR(17)
)
七、下面是用C#写的调用SQL_LOADER的方法
Private Function Exec_SqlLoader(ByVal s_aFilePath As String, ByVal o_afileName As Hashtable, ByRef s_aErrMsg As String) As Boolean FilePath = s_aFilePath.Trim(\"\\\")
Dim ctlPath As String = FilePath + \"\\control\" s_aErrMsg = \"\" Try
For i As Integer = 1 To 4
Dim strmReader As New StreamReader(ctlPath + \"\\001\" + i.ToString() + \".ctl\") Dim ctlContent As String = strmReader.ReadToEnd()
ctlContent = ctlContent.Replace(\"{{dataFile}}\ strmReader.Close() strmReader = Nothing
Dim strCtlName As String = ctlPath + \"\\001\" + i.ToString() + \"new.ctl\" Dim strLogName As String = ctlPath + \"\\001\" + i.ToString() + \"new.log\" Dim strBadName As String = ctlPath + \"\\001\" + i.ToString() + \"new.bad\" Dim strDscName As String = ctlPath + \"\\001\" + i.ToString() + \"new.dsc\" Dim strmWriter As StreamWriter = File.CreateText(strCtlName) strmWriter.Write(ctlContent) strmWriter.Close() strmWriter = Nothing
If (File.Exists(strBadName)) Then File.Delete(strBadName) End If
Dim connSetting As String() = thisVersion.MSD_ConnectionStr.Split(\";\") Dim serviceName As String = CType(connSetting.GetValue(0), String) serviceName = serviceName.Substring(serviceName.IndexOf(\"=\") + 1) Dim userId As String = CType(connSetting.GetValue(1), String) userId = userId.Substring(userId.IndexOf(\"=\") + 1)
Dim password As String = CType(connSetting.GetValue(2), String) password = password.Substring(password.IndexOf(\"=\") + 1) Dim strPathName As String
strPathName = \"sqlldr \" + userId + \"/\" + password + \"@\" + serviceName + \" control='\" + strCtlName + \"' log='\" + strLogName + \"' bad='\" + strBadName + \"' discard='\" + strDscName + \"' errors=500\"
Microsoft.VisualBasic.Shell(strPathName, AppWinStyle.MinimizedFocus, True) If (File.Exists(strBadName)) Then
File.Copy(strBadName, FilePath + \"\\BatchLog\\ERROR_001\" + i.ToString() + \".txt\True)
a_sErrMsg += \"这里写抛出的警告信息\" + vbCrLf + vbTab End If Next Return True Catch ex As Exception
a_sErrMsg += ex.ToString() ms_BatchLogMsg = ex.Message Return False End Try End Function
因篇幅问题不能全部显示,请点此查看更多更全内容