数据没有从sql加载器填充

Gau*_*oni 1 oracle oracle10g sql-loader

我有一个控制文件,loader.ctl,in C:\oracle\product\10.2.0\oradata\orcl.

loader.ctl文件的内容是

 load data
 infile 'd:\mydata\test.csv'
 into table emp1
 fields terminated by "," optionally enclosed by '"'          
 ( empno, ename,job,mgr,hiredate,sal,comm,deptno )
Run Code Online (Sandbox Code Playgroud)

emp1 table已存在于数据库中,test.csv中有9条记录

我从sqlldr执行了loader.ctl:

在此输入图像描述

现在,当我检查我的数据库时,我发现没有记录emp1...为什么会这样?提交之后为什么表中没有填充数据?

Ben*_*Ben 7

首先,您没有指定日志文件,这意味着它可能与您的ctl文件位于同一位置,但它也可能位于您调用SQL*Loader的目录或数据所在的目录中 - 除此之外它是一个好的想要从存储ctl文件的同一个地方调用SQL*Loader以避免混淆.去寻找它和相关的坏文件.

我总是会在命令行或ctl文件中明确说明日志和坏的位置 - 并在适当时丢弃文件.我更喜欢命令行,因此您可以将它们全部放在不同的文件夹中,这样它们就不会相互覆盖.因此,每次加载时都不必更改ctl文件,也可以将数据文件(以及其他几乎所有内容)放在命令行中.像这样的东西:

call sqlldr scott/tiger@mydb my_ctl.ctl data=d:\20110201\my_file.csv log=d:\20110201\my_log.log bad=d:\20110201\my_bad.bad   
Run Code Online (Sandbox Code Playgroud)

您的问题有两个可能的原因.

  1. 正如@JustinCave建议你只是从错误的表中选择.我们暂时不谈这个.

  2. 您已经注意到您已达到提交点,因此表中应该有数据.事实并非如此.您已到达提交点,但是,根据您发布的ctl文件,您尚未指定允许的错误数.这意味着SQL*Loader使用默认值 - 50.它可以到达一个提交点,在它之前加载的所有东西都是错误的; 即你什么都不做.

第2点是导致问题的最可能原因.查看日志文件,它应该以一种不一定非常有用的方式告诉您,为什么您会遇到错误.坏文件包含尚未加载的所有数据,您可以根据日志进行检查.

第二个出现的原因有很多,所以这里列出了SQL*Loader可能出错的事情:

  1. 您的ctl列和表列不会使用完全相同的名称调用.
  2. 您的文件不存在.
  3. 你的桌子不存在.
  4. 文件末尾有分隔符,这意味着您需要添加选项TRAILING NULLCOLS.
  5. 你在一条线的中间有一条新线 - 你遇到了大麻烦.您需要使用完整的ctl和表格描述以及示例数据来提出另一个问题.
  6. 表中的一列是日期数据类型.由于csv中的每一段数据都是一个字符串SQL*Loader无法将其转换为日期.我将假设这是hiredate,这将成为hiredate "to_date(:hiredate,'yyyy/mm/dd')"ctl文件,其中yyyy/mm/dd更改为您需要的任何日期格式.在这里看到一个很好的清单.当然,您始终可以将此列更改为char并稍后处理转换.
  7. 表中的一列是数字数据类型,您正在尝试将非数字加载到其中.抱歉,在这种情况下,您需要将列的数据类型更改为char.
  8. 表中的一列是一个数字,您正在尝试将格式化的数字插入其中.请记住,逗号和小数点不是数字,在这种情况下,您可以使用以下to_number函数:sal "to_number(:sal,'999.99')".与日期一样,您可以随时将此列更改为char并稍后处理转换.
  9. 在csv的每一行的末尾都有一个新行,它使列的长度超过最大值.更改deptnodeptno terminated by whitespace.
  10. 表中的字段不够大.
  11. 您正在将多字节数据(例如UTF-8)加载到字节语义表中,这意味着字符数相同但字节数太少.将其更改为char semantic.
  12. 一个数字在末尾有一个空格,让我们说这也是sal,你应该把sal integer external它更改为,它明确告诉SQL*Loader它是一个数字.
  13. 您的文件称为csv,但实际上并非如此.有人将管道分隔的文本文件重命名为csv(这只是我可以给出的数百个例子中的一个例子 - .txt.exe任何人?)
  14. 最简单的原因,应该在顶部,是csv中的数据与表的规范无关.
  15. csv文件中的字符集与数据库中的字符集不同,Oracle在翻译时遇到问题.使用该characterset选项.

在我的头脑中,大部分可能出现的问题与你的负载一样简单.

现在的建议.指定.就这么简单.如果你没有利用SQL*Loader极其强大的特性和它提供的无数选项,你会遇到这样的问题.不仅当供应商改变某些事情而不告诉您不太可能注意到变化时.

我强烈建议在加载后总是检查日志文件.通常,这是检查负载是否成功的唯一方法之一.SQL*Loader几乎在每个错误栏上都无声地失败ORA-01653- 没有足够的空间并将有关这些错误的所有信息放在日志文件中.除非你检查,否则你不会知道它们.

典型的ctl文件通常看起来像这样:

OPTIONS ( skip=1, errors=10, rows=10000, direct=True)
LOAD DATA
 INFILE 'd:\mydata.csv'
 TRUNCATE 
 INTO TABLE emp1
 FIELDS TERMINATED BY "," 
 OPTIONALLY ENLCOSED BY '"'
 TRAILING NULLCOLS
 (  empno
  , ename
  , job
  , mgr
  , hiredate "to_date(:hiredate,'dd/mm/yy')"
  , sal integer external
  , comm
  , deptno terminated by whitespace
 )
Run Code Online (Sandbox Code Playgroud)

所有这些,禁止列名和表名是可选的.

我添加的是:

  • skip - 要跳过的顶部的行数.
  • errors - 停止前的最大错误数.
  • rows - 提交前要加载的行数.
  • direct - 使用直接路径加载.
  • TRUNCATE - 在加载之前截断表
  • TRAILING NULLCOLS - 文件末尾有空列.
  • "to_date(..." - 指定加载此列时要调用的Oracle函数
  • integer external - 强制此列为数字数据类型.
  • terminated by whitespace - 删除行或列末尾的空格.

有更多的负载.

以下是一些非常适合进一步阅读的链接,以及对您可用的所有可能选项的更多解释:

http://docs.oracle.com/cd/B19306_01/server.102/b14215/ldr_params.htm
http://www.orafaq.com/wiki/SQL*Loader_FAQ
http://www.oracleutilities.com/OSUtil/ sqlldr.html