在用SQL Loader加载数据时,有两个问题,求解决:
1.因为我的数据文件没有扩展名,结果我在导入时,oracle自动加上.dat扩展名。是否可以进行限制,不让oracle自动加上.dat的默认扩展名?2.因为导入的数据中有日期类型,而我在控制文件中并没有指定具体类型。是否可以在进行什么设置,让Sqlloader自动识别指定的日期格式,而不需要指定去每个一字段指定日期类型格式。谢谢。
1.因为我的数据文件没有扩展名,结果我在导入时,oracle自动加上.dat扩展名。是否可以进行限制,不让oracle自动加上.dat的默认扩展名?2.因为导入的数据中有日期类型,而我在控制文件中并没有指定具体类型。是否可以在进行什么设置,让Sqlloader自动识别指定的日期格式,而不需要指定去每个一字段指定日期类型格式。谢谢。
解决方案 »
- oracle数据库如何循环取表的列值
- 求ORACLE帝,ORACLE帝快快现身~~~~~~~~小弟真心求教~~~
- 如何在表中加唯一性索引?
- 请问一下如何在pl/sql中运行存储过程阿?
- oracle问题
- 我在2000系统装了9I,装完后发现IIS中的默认网站不能启动了,说是IP被占用了
- 我刚才发的帖子怎么没显示??再贴一遍把, 关于oracle没有响应的问题
- 这个sql为什么运行得这么慢?
- oracle9I刚刚安装完毕
- 用dblink同步数据时发现数据重复
- 请教 oracle oci 的 OCI_SUCCESS_WITH_INFO 错误的具体原因,以及解决方法。
- windows 2008 装 oracle 10g 问题
-- 使用SQLLDR加载日期相当简单,但是看起来这个方面经常导致混淆。你只需在控制文件中使用DATE数据类型,并指定要使用的日期掩码。
-- 这个日期掩码与数据库中TO_CHAR和TO_DATE中使用的日期掩码是一样的。SQLLDR会向数据应用这个日期掩码,并为你完成加载。-- 例如,如果再把DEPT表修改如下:
alter table dept add last_updated date;-- 可以用以下控制文件加载它:
LOAD DATA
INFILE *
INTO TABLE DEPT
REPLACE
FIELDS TERMINATED BY ','
( DEPTNO,
DNAME,
LOC,
LAST_UPDATED date 'dd/mm/yyyy'
)
BEGINDATA
10,Sales,Virginia,1/5/2000
20,Accounting,Virginia,21/6/1999
30,Consulting,Virginia,5/1/2000
40,Finance,Virginia,15/3/2001-- 所得到的DEPT表如下所示:eygle@SZTYORA> select * from dept; DEPTNO DNAME LOC LAST_UPDATED
---------- ---------------------------- -------------------------- -------------------
10 Sales Virginia 2000-05-01 00:00:00
20 Accounting Virginia 1999-06-21 00:00:00
30 Consulting Virginia 2000-01-05 00:00:00
40 Finance Virginia 2001-03-15 00:00:00-- 就这么简单。只需在控制文件中应用格式,SQLLDR就会为我们完成日期转换。在某些情况下,可能使用一个更强大的SQL函数更为合适。例如,
-- 如果你的输入文件包含多种不同格式的日期:有些有时间分量,有些没有;有些采用DD-MON-YYYY格式;有些格式为DD/MM/YYYY;等等。
-- 在下一节中你会了解到如何在SQLLDR中使用函数来解决这些问题。
-- SQL*Loader(SQLLDR)是Oracle的高速批量数据加载工具。这是一个非常有用的工具,可用于从多种平面文件格式向Oracle数据库中加载数据。
-- SQLLDR可以在极短的时间内加载数量庞大的数据。它有两种操作模式:
-- *(01) 传统路径(conventional path):SQLLDR会利用SQL插入为我们加载数据。
-- *(02) 直接路径(direct path):采用这种模式,SQLLDR不使用SQL;而是直接格式化数据库块。-- 利用直接路径加载,你能从一个平面文件读数据,并将其直接写至格式化的数据库块,而绕过整个SQL引擎和undo生成,同时还可能避开redo生成。
-- 要在一个没有任何数据的数据库中充分加载数据,最快的方法就是采用并行直接路径加载。......-- 需要指出,在Oracle 8.1.6 Release 1及以上版本中,Oracle调用接口(Oracle Call Interface, OCI)允许使用C编写你自己的直接路径加载工具。
-- 如果你要执行的操作在SQLLDR中做不到,或者如果需要SQLLDR与你的应用无缝集成,Oracle OCI就很有用。SQLLDR是一个命令行工具(也就是说,这是一个单独的程序)。
-- 它并非一个API,例如,不能“从PL/SQL调用”。......-- 要使用SQLLDR,需要有一个控制文件(control file)。控制文件中包含描述输入数据的信息(如输入数据的布局、数据类型等),另外还包含有关目标表的信息。
-- 控制文件甚至还可以包含要加载的数据。在下面的例子中,我们将一步一步地建立一个简单的控制文件,并对这些命令提供必要的解释
-- (注意,代码左边加括号的数并不是控制文件中的一部分,显示这些数只是为了便于引用)。(01) LOAD DATA
(02) INFILE *
(03) INTO TABLE DEPT
(04) FIELDS TERMINATED BY ','
(05) (DEPTNO, DNAME, LOC )
(06) BEGINDATA
(07) 10,Sales,Virginia
(08) 20,Accounting,Virginia
(09) 30,Consulting,Virginia
(10) 40,Finance,Virginia-- *(01) LOAD DATA:这会告诉SQLLDR要做什么(在这个例子中,则指示要加载数据)。SQLLDR还可以执行CONTINUE_LOAD,也就是继续加载。
-- 只有在继续一个多表直接路径加载时才能使用后面这个选项。
-- *(02) INFILE *:这会告诉SQLLDR所要加载的数据实际上包含在控制文件本身中,如第6~10行所示。也可以指定包含数据的另一个文件的文件名。如果愿意,
-- 可以使用一个命令行参数覆盖这个INFILE语句。要当心,命令行选项总会覆盖控制文件设置。
-- *(03) INTO TABLE DEPT:这会告诉SQLLDR要把数据加载到哪个表中(在这个例子中,数据要加载到DEPT表)。
-- *(04) FIELDS TERMINATED BY ',':这会告诉SQLLDR数据的形式应该是用逗号分隔的值。为SQLLDR描述输入数据的方式有数十种;这只是其中较为常用的方法之一。
-- *(05) DEPTNO, DNAME, LOC:这会告诉SQLLDR所要加载的列、这些列在输入数据中的顺序以及数据类型。这是指输入流中数据的数据类型,而不是数据库中的数据类型。
-- 在这个例子中,列的数据类型默认为CHAR(255),这已经足够了。
-- *(06) BEGINDATA:这会告诉SQLLDR你已经完成对输入数据的描述,后面的行(第7~10行)是要加载到DEPT表的具体数据。......-- 这个控制文件采用了最简单、最常用的格式之一:将定界数据加载到一个表。这一章还会看到一些复杂的例子,不过可以从这个简单的控制文件入手,这是一个不错的起点。
-- 要使用这个控制文件(名为demo1.ctl),只需创建一个空的DEPT表:create table dept
( deptno number(2) constraint dpet_pk primary key,
dname varchar2(14),
loc varchar2(13)
)
/-- 并运行以下命令:sqlldr userid=/ control=demo1.ctl-- sqlldr eygle/eygle control=demo1.ctl-- 如果表非空,就会收到一个错误消息:SQL*Loader-601: 对于 INSERT 选项, 表必须为空。表 DEPT 上出错-- 这是因为:这个控制文件中几乎所有选项都取默认值,而默认的加载选项是INSERT(而不是APPEND、TRUNCATE或REPLACE)。要执行INSERT,SQLLDR就认为表为空。
-- 如果想向DEPT表中增加记录,可以指定加载选项为APPEND;或者,为了替换DEPT表中的数据,可以使用REPLACE或TRUNCATE。REPLACE使用一种传统DELETE语句;因此,
-- 如果要加载的表中已经包含许多记录,这个操作可能执行得很慢。TRUNCATE则不同,它使用TRUNCATE SQL命令,通常会更快地执行,因为它不必物理地删除每一行。-- 15.1.1 用SQLLDR加载数据的FAQ ( P660 )
-- 现在来回答Oracle数据库中关于用SQLLDR加载数据最常问到的一些问题。-- *1) 如果加载定界数据?
-- 定界数据(delimited data)即用某个特殊字符分隔的数据,可能用引号括起,这是当前平面文件最常见的数据格式。在大型机上,定长、固定格式的文件可能是最可识别的文件格式,
-- 但是在UNIX和NT上,定界文件才是“标准”。在这一节中,我们将分析用于加载定界数据的常用选项。-- 对于定界数据,最常用的格式是逗号分隔值(comma-separated values, CSV)格式。采用这种文件格式,数据中的每个字段与下一个字段用一个逗号分隔。文本串可以用引号括起,
-- 这样就允许串本身包含逗号。如果串还必须包含引号,一般约定是使用两个引号(在下面的代码中,我们将使用" "而不是' ')。要加载定界数据,
-- 相应的典型控制文件与前面第一个例子很相似,但是FIELDS TERMINATED BY子句通常如下指定:
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'-- 它指定用逗号分隔数据字段,每个字段可以用双引号括起。如果我们把这个控制文件的最后部分修改如下:
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
(DEPTNO, DNAME, LOC )
BEGINDATA
10,Sales,"Virginia,USA"
20,Accounting,"Va,""USA"""
30,Consulting,Virginia
40,Finance,Virginia-- 使用这个控制文件运行SQLLDR时,结果如下:
eygle@SZTYORA> select * from dept; DEPTNO DNAME LOC
---------- ---------------------------- --------------------------
10 Sales Virginia,USA
20 Accounting Va,"USA"
30 Consulting Virginia
40 Finance Virginia-- 要特别注意以下几点:
-- *(01) 部门10中的Virginia,USA:这是因为输出数据是"Virginia,USA"。输入数据字段必须包括在引号里才能保留数据中的逗号。否则,
-- 数据中的这个逗号会被认为是字段结束标记,这样就会只加载Virginia,而没有USA文本。
-- *(02) Va, "USA":这是因为输入数据是"Va, ""USA"""。对于引号括起的串,SQLLDR会把其中"的两次出现计为一次出现。
-- 要加载一个包含可选包围字符(enclosure character)的串,必须保证这个包围字符出现两次。-- 另一种常用的格式是制表符定界数据(tag-delimited data),这是用制表符分隔而不是逗号分隔的数据。有两种方法使用TERMINATED BY子句来加载这种数据:
-- *(01) TERMINATED BY X'09' (使用十六进制格式 的制表符:采用ASCII时,制表符为9)
-- *(02) TERMINATED BY WHITESPACE-- 这两种方法在实现上有很大差异,下面将会说明。还是用前面的DEPT表,我们将使用以下控制文件加载这个表:
LOAD DATA
INFILE *
INTO TABLE DEPT
REPLACE
FIELDS TERMINATED BY WHITESPACE
(DEPTNO, DNAME, LOC)
BEGINDATA
10 Sales Virgina-- 从字面上不太容易看得出来,不过要知道,在这里各部分数据之间都有两个制表符。这里的数据行实际上是:
10\t\tSales\t\tVirginia-- 在此\t
普遍可识别的制表符转义字符。使用这个控制文件时(包含如前所示的TERMINATED BY WHITESPACE),表DEPT中的数据将是:
eygle@SZTYORA> select * from dept; DEPTNO DNAME LOC
---------- ---------------------------- --------------------------
10 Sales Virgina-- TERMINATED BY WHITESPACE会解析这个串,查询空白符(制表符、空格或换行符)的第一次出现,然后继续查询,直至找到下一个非空白符。因此,解析数据时,
-- DEPTNO会赋给10,后面的两个制表符被认为是空白符,Sales会赋给DNAME等。-- 另一方面,如果要使用FIELDS TERMINATED BY X'09',如以下控制文件所示,这里稍做修改:LOAD DATA
INFILE *
INTO TABLE DEPT
REPLACE
FIELDS TERMINATED BY X'09'
(DEPTNO, DNAME, LOC)
BEGINDATA
10 Sales Virgina-- 可以看到DEPT中加载了以下数据:
eygle@SZTYORA> select * from dept; DEPTNO DNAME LOC
---------- ---------------------------- --------------------------
10 Sales-- 在此,一旦SQLLDR遇到一个制表符,就会输出一个值。因此,将10赋给DEPTNO,DNAME得到了NULL,因为在第一个制表符和制表符的下一次出现之间没有数据。Sales赋给了LOC。-- 这是TERMINATED BY WHITESPACE和TERMINATED BY <character>的有意行为。至于使用哪一种方法更合适,这取决于输入数据以及你要如何解释输入数据。......-- 最后,加载这样的定界数据时,很可能想跳过输入记录中的某些列。例如,你可能想加载字段1、3和5,而跳过第2列和第4列。为此,SQLLDR提供了FILLER关键字。
-- 这允许你映射一个输入记录中的一列,但不把它放在数据库中。例如,给定DEPT表以及先前的最后一个控制文件,可以修改这个控制文件,使用FILLER关键字正确地加载数据(跳过制表符):LOAD DATA
INFILE *
INTO TABLE DEPT
REPLACE
FIELDS TERMINATED BY X'09'
(DEPTNO, dummy1 filler, DNAME, dummy2 filler, LOC)
BEGINDATA
10 Sales Virgina-- 所得到的表DEPT现在如下所示:eygle@SZTYORA> select * from dept; DEPTNO DNAME LOC
---------- ---------------------------- --------------------------
10 Sales Virgina-- *2) 如何加载固定格式数据? ( P662 )
-- 通常会有一个由某个外部系统生成的平面文件,而且这是一个定长文件,其中包含着固定位置的数据(positional data)。
-- 例如,NAME字段位于第1~10字节,ADDRESS字段位于第11~35字节等。我们将介绍SQLLDR如何为我们导入这种数据。-- 这种定宽的固定位置数据是最适合SQLLDR加载的数据格式。要加载这种数据,使用SQLLDR是最快的处理方法,因为解析输入数据流相当容易。
-- SQLLDR会在数据记录中存储固定字符偏移量和长度,因此抽取某个给定字段相当简单。如果要加载大量数据,将其转换为一种固定位置格式通常是最好的办法。当然,
-- 定宽文件也有一个缺点,它比简单的定界文件格式可能要大得多。-- 要加载定宽的固定位置数据,将会在控制文件中使用POSITION关键字,例如:
LOAD DATA
INFILE *
INTO TABLE DEPT
REPLACE
( DEPTNO position(1:2),
DNAME position(3:16),
LOC position(17:29)
)
BEGINDATA
10Accounting Virginia,USA-- 这个控制文件没有使用FIELDS TERMINATED BY子句;而是使用了POSITION来告诉SQLLDR字段从哪里开始,到哪里结束。关于POSITION子句有意思的是,我们可以使用重叠的位置,
-- 可以在记录中来回反复。例如,如果如下修改DEPT表:alter table dept add entire_line varchar(29);-- 并使用以下控制文件:
LOAD DATA
INFILE *
INTO TABLE DEPT
REPLACE
( DEPTNO position(1:2),
DNAME position(3:16),
LOC position(17:29),
ENTIRE_LINE position(1:29)
)
BEGINDATA
10Accounting Virginia,USA-- 字段ENTIRE_LINE定义为POSITION(1:29)。这会从所有29字节的输入中抽取出这个字段的数据,而其他字段都是输入数据的子串。这个控制文件的输出如下:eygle@SZTYORA> select * from dept; DEPTNO DNAME LOC ENTIRE_LINE
---------- ---------------------------- -------------------------- ----------------------------------------------------------
10 Accounting Virginia,USA 10Accounting Virginia,USA-- 使用POSITION时,可以使用相对偏移量,也可以使用绝对偏移量。在前面的例子中使用了绝对偏移量,我们明确地指示了字段从哪里开始,到哪里结束。也可以把前面的控制文件写作:
LOAD DATA
INFILE *
INTO TABLE DEPT
REPLACE
( DEPTNO position(1:2),
DNAME position(*:16),
LOC position(*:29),
ENTIRE_LINE position(1:29)
)
BEGINDATA
10Accounting Virginia,USA-- *指控制文件得出上一个字段在哪里结束。因此,在这种情况下,(*:16)与(3:16)是一样的。注意,控制文件中可以混合使用相对位置和绝对位置。另外。
-- 使用*表示法时,可以把它与偏移量相加。例如,如果DNAME从DEPTNO结束之后第2个字节处开始,可以使用(*+2:16)。-- POSITION子句中的结束位置必须是数据结束的绝对列位置。有时,可能指定每个字段的长度更为容易,特别是如果这些字段是连续的(就像前面的例子一样)。
-- 采用这种方式,只需告诉SQLLDR:记录从第1个字节开始,然后指定每个字段的长度就行了。这样我们就可以免于计算记录中的开始和结束偏移量,这个计算有时可能很困难。
-- 为此,可以不指定结束位置,而是指定定长记录中的各个字段的长度,如下:
LOAD DATA
INFILE *
INTO TABLE DEPT
REPLACE
( DEPTNO position(1) char(2),
DNAME position(*) char(14),
LOC position(*) char(13),
ENTIRE_LINE position(1) char(29)
)
BEGINDATA
10Accounting Virginia,USA-- 在此只需告诉SQLLDR第一个字段从哪里开始及其长度。后面的每个字段都从上一个字段结束处开始,并具有指定的长度。直至最后一个字段才需要再次指定位置,
-- 因为这个字段又要从记录起始处开始。
-- 在这一节中,我们将介绍加载数据时如何使用函数-- 一旦你了解了SQLLDR如何构建其INSERT语句,在SQLLDR中使用函数就很容易了。要在SQLLDR脚本中向某个字段应用一个函数,只需将这个函数增加到控制文件中(用两个引号括起)。
-- 例如,假设有前面的DEPT表,你想确保所加载的数据都是大写的。可以使用以下控制文件来加载:LOAD DATA
INFILE *
INTO TABLE DEPT
REPLACE
FIELDS TERMINATED BY ','
( DEPTNO,
DNAME "upper(:dname)",
LOC "upper(:loc)",
LAST_UPDATED date 'dd/mm/yyyy'
)
BEGINDATA
10,Sales,Virginia,1/5/2000
20,Accounting,Virginia,21/6/1999
30,Consulting,Virginia,5/1/2000
40,Finance,Virginia,15/3/2001-- 数据库中得到的数据如下:eygle@SZTYORA> select * from dept; DEPTNO DNAME LOC LAST_UPDATED
---------- ---------------------------- -------------------------- -------------------
10 SALES VIRGINIA 2000-05-01 00:00:00
20 ACCOUNTING VIRGINIA 1999-06-21 00:00:00
30 CONSULTING VIRGINIA 2000-01-05 00:00:00
40 FINANCE VIRGINIA 2001-03-15 00:00:00-- 可以注意到,只需向一个绑定变量应用UPPER函数就可以很容易地将数据变为大写。要注意,SQL函数可以引用任何列,而不论将函数实际上应用于哪个列。这说明,
-- 一个列可以是对两个或更多其他列应用一个函数的结果。例如,如果你想加载ENTIRE_LINE列,可以使用SQL连接运算符。不过,这种情况下这样做稍有些麻烦。现在,
-- 输入数据集中有4个数据元素。如果只是向控制文件中如下增加ENTIRE_LINE:LOAD DATA
INFILE *
INTO TABLE DEPT
REPLACE
FIELDS TERMINATED BY ','
( DEPTNO,
DNAME "upper(:dname)",
LOC "upper(:loc)",
LAST_UPDATED date 'dd/mm/yyyy',
ENTIRE_LINE ":deptno||:dname||:loc||:last_updated"
)
BEGINDATA
10,Sales,Virginia,1/5/2000
20,Accounting,Virginia,21/6/1999
30,Consulting,Virginia,5/1/2000
40,Finance,Virginia,15/3/2001-- 就会看到,日志文件中对于每个输入记录出现以下错误:
Record 1: Rejected - Error on table DEPT, column ENTIRE_LINE.
Column not found before end of logical record (use TRAILING NULLCOLS)记录 1: 被拒绝 - 表 DEPT 的列 ENTIRE_LINE 出现错误。
在逻辑记录结束之前未找到列 (使用 TRAILING NULLCOLS)-- 在此,SQLLDR告诉你:没等处理完所有列,记录中就没有数据了。这种情况下,解决方案很简单。实际上,SQLLDR甚至已经告诉了我们该怎么做:这就是使用TRAILING NULLCOLS。
-- 这样一来,如果输入记录中不存在某一列的数据,SQLLDR就会为该列绑定一个NULL值。在这种情况下,增加TRAILING NULLCOLS会导致绑定变量:ENTIRE_LINE成为NULL。
-- 所以再尝试这个控制文件:LOAD DATA
INFILE *
INTO TABLE DEPT
REPLACE
FIELDS TERMINATED BY ','
TRAILING NULLCOLS
( DEPTNO,
DNAME "upper(:dname)",
LOC "upper(:loc)",
LAST_UPDATED date 'dd/mm/yyyy',
ENTIRE_LINE ":deptno||:dname||:loc||:last_updated"
)
BEGINDATA
10,Sales,Virginia,1/5/2000
20,Accounting,Virginia,21/6/1999
30,Consulting,Virginia,5/1/2000
40,Finance,Virginia,15/3/2001-- 现在表中的数据如下:eygle@SZTYORA> select * from dept; DEPTNO DNAME LOC LAST_UPDATED ENTIRE_LINE
---------- ---------------------------- -------------------------- ------------------- ----------------------------------------------------------
10 SALES VIRGINIA 2000-05-01 00:00:00 10SalesVirginia1/5/2000
20 ACCOUNTING VIRGINIA 1999-06-21 00:00:00 20AccountingVirginia21/6/1999
30 CONSULTING VIRGINIA 2000-01-05 00:00:00 30ConsultingVirginia5/1/2000
40 FINANCE VIRGINIA 2001-03-15 00:00:00 40FinanceVirginia15/3/2001-- 之所以可以这样做,原因在于SQLLDR构建其INSERT语句的做法。SQLLDR会查看前面的控制文件,并看到控制文件中的DEPTNO、DNAME、LOC、LAST_UPDATED和ENTIRE_LINE这几列。
-- 它会根据这些列建立5个绑定变量。通常,如果没有任何函数,所建立的INSERT语句就是:
INSERT INTO DEPT ( DEPTNO, DNAME, LOC, LAST_UPDATED, ENTIRE_LINE )
VALUES ( :DEPTNO, :DNAME, :LOC, :LAST_UPDATED, :ENTIRE_LINE );-- 然后再解析输入流,将值赋给相应的绑定变量,然后执行语句。如果使用函数,SQLLDR会把这些函数结合到INSERT语句中。在上一个例子中,SQLLDR建立的INSERT语句如下所示:
INSERT INTO DEPT ( DEPTNO, DNAME, LOC, LAST_UPDATED, ENTIRE_LINE )
VALUES ( :DEPTNO, upper(:dname), upper(:loc), :last_updated,
:deptno||:dname||:loc||:last_updated );-- 然后再做好准备,把输入绑定到这个语句,再执行语句。所以,SQL中能做的事情都可以结合到SQLLDR脚本中。由于SQL中增加了CASE语句,所以这样做不仅功能极为强大,
-- 而且相当容易。例如,假设你的输入文件有以下格式的日期:-- *(01) HH24:MI:SS:只有一个时间;日期默认为SYSDATE。
-- *(02) DD/MM/YYYY:只有一个日期;时间默认为午夜0点。
-- *(03) HH24:MI:SS DD/MM/YYYY:日期和时间都要显式提供。-- 可以使用如下的一个控制文件:LOAD DATA
INFILE *
INTO TABLE DEPT
REPLACE
FIELDS TERMINATED BY ','
TRAILING NULLCOLS
( DEPTNO,
DNAME "upper(:dname)",
LOC "upper(:loc)",
LAST_UPDATED
"case
when length(:last_updated) > 9 then to_date(:last_updated,'hh24:mi:ss dd/mm/yyyy')
when instr(:last_updated,':') > 0 then to_date(:last_updated,'hh24:mi:ss')
else to_date(:last_updated,'dd/mm/yyyy')
end"
)
BEGINDATA
10,Sales,Virginia,12:03:03 17/10/2005
20,Accounting,Virginia,02:23:54
30,Consulting,Virginia,01:24:00 21/10/2005
40,Finance,Virginia,17/8/2005-- 可以得到以下结果:
eygle@SZTYORA> select * from dept; DEPTNO DNAME LOC LAST_UPDATED
---------- ---------------------------- -------------------------- -------------------
10 SALES VIRGINIA 2005-10-17 12:03:03
20 ACCOUNTING VIRGINIA 2011-03-01 02:23:54
30 CONSULTING VIRGINIA 2005-10-21 01:24:00
40 FINANCE VIRGINIA 2005-08-17 00:00:00-- 现在向输入字符应用3个日期格式中的一个(注意,这里不再加载一个DATE;而只是加载一个串)。CASE函数会查看串的长度和内容,从而确定应该使用哪一个掩码。-- 有意思的是,你可以编写自己的函数来由SQLLDR调用。这直接应验了可以从SQL调用PL/SQL。
但是我没有找到答案,
我不想在控制文件中指定日期的格式 ,我想让sqlloader 自已去识别,
因为,我的控制文件是程序自己动生成的。
-- 还有:程序能够自己生成控制文件,就不能在date类型的字段指定其格式?
如果我 alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'
那在insert时,就不要转类型了。
-- 但是记住:SQLLDR是一个命令行工具(也就是说,这是一个单独的程序)。它并非一个API,例如,不能“从PL/SQL调用”。
-- 其原因:我上面已经说清楚啦!
-- *1) 假设你有一个用户 eygle,其密码也为 eygle
-- *2) 假设用户eygle下有表dept,建表代码如下:
CREATE TABLE "EYGLE"."DEPT"
( "DEPTNO" NUMBER(2,0),
"DNAME" VARCHAR2(14),
"LOC" VARCHAR2(13),
"LAST_UPDATED" DATE
);-- *3) 在c盘根目录下创建名为sqlldr.ctl的控制文件,其内容如下:(因为你的文件没有扩展名,所以 INFILE 'c:\dept_data.',在文件名后面加个句点就可以啦)
LOAD DATA
INFILE 'c:\dept_data.'
INTO TABLE DEPT
REPLACE
FIELDS TERMINATED BY ','
( DEPTNO,
DNAME,
LOC,
LAST_UPDATED date 'dd/mm/yyyy'
)-- *4) 在c盘根目录下创建名为 dept_data (没有扩展名) 的数据文件,内容如下:
10,Sales,Virginia,1/5/2000
20,Accounting,Virginia,21/6/1999
30,Consulting,Virginia,5/1/2000
40,Finance,Virginia,15/3/2001-- *5) 执行导入数据:
C:\>sqlldr eygle/eygle control=c:\sqlldr.ctlSQL*Loader: Release 10.2.0.1.0 - Production on 星期四 3月 31 15:18:20 2011Copyright (c) 1982, 2005, Oracle. All rights reserved.达到提交点 - 逻辑记录计数 3
达到提交点 - 逻辑记录计数 4-- *6) 验证表中数据是否成功导入!eygle@SZTYORA> select * from dept; DEPTNO DNAME LOC LAST_UPDATED
---------- ---------------------------- -------------------------- -------------------
10 Sales Virginia 2000-05-01 00:00:00
20 Accounting Virginia 1999-06-21 00:00:00
30 Consulting Virginia 2000-01-05 00:00:00
40 Finance Virginia 2001-03-15 00:00:00
你给出的代码,只在window平台有效,到 solaris或AIX 下不行了