数据没有从sql加载器填充

时间:2012-02-01 17:54:12

标签: oracle oracle10g sql-loader

我在C:\oracle\product\10.2.0\oradata\orcl中有一个控制文件loader.ctl。

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 )

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

我从sqlldr执行了loader.ctl:

enter image description here

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

1 个答案:

答案 0 :(得分:8)

首先,您还没有指定日志文件,这意味着它可能与您的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   

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

  1. 正如@JustinCave建议您只是从错误的表格中选择。我们现在暂且不谈。

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

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

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

    1. 您的ctl列和表列不会被完全调用相同的名称。
    2. 您的档案不存在。
    3. 你的桌子不存在。
    4. 您的文件末尾有分隔符,这意味着您需要添加选项TRAILING NULLCOLS
    5. 你在一条线的中间有一条新线 - 你遇到了大麻烦。您需要使用完整的ctl和表格描述以及示例数据来提出另一个问题。
    6. 表中的一列是日期数据类型。由于csv中的每一段数据都是一个字符串,因此SQL * Loader无法将其转换为日期。我假设这是hiredate,它将在ctl文件中变为hiredate "to_date(:hiredate,'yyyy/mm/dd')",其中yyyy/mm/dd将更改为您需要的任何日期格式。有关好的列表,请参阅here。当然,您可以随时将此列更改为char并稍后处理转换。
    7. 表格中的一列是数字数据类型,您正在尝试将非数字加载到其中。抱歉,在这种情况下,您需要将列的数据类型更改为char。
    8. 表格中的一列是一个数字,您正在尝试将格式化的数字插入其中。请记住,逗号和小数点不是数字,在这种情况下,您可以使用to_number函数:sal "to_number(:sal,'999.99')"。与日期一样,您可以随时将此列更改为char并稍后处理转换。
    9. csv中每行末尾都有一个新行,它使列的长度超过最大值。将deptno更改为deptno 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选项。
    16. 在我的头脑中,大部分可能出现的错误都是像你的一样简单。

      现在的建议。的指定即可。它就这么简单。如果你不利用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
       )
      

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

      我添加的是

      • 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