外部表 - 使用FIXED时“文件末尾的部分记录”错误

时间:2011-10-16 14:05:12

标签: database oracle plsql oracle11g external-tables

在外部表格中使用FIXED参数时,我在文件结尾处获得“部分记录”错误。

我正在使用SQL Developer,Oracle 11g XE。

-------
foo.dat - Field lengths: fname=7;lname=8;year=4
-------
Alvin  Tolliver1976
KennethBaer    1963
Mary   Dube    1973 

这是表格的DDL:

CREATE TABLE emp_load (
    first_name CHAR(7)
    , last_name CHAR(8)
    , year_of_birth CHAR(4)
)
  ORGANIZATION EXTERNAL (
     TYPE ORACLE_LOADER 
     DEFAULT DIRECTORY ext_tab_dir
     ACCESS PARAMETERS (
           RECORDS FIXED 20 FIELDS (
               first_name CHAR(7)
               , last_name CHAR(8)
               ,  year_of_birth CHAR(4)
               )
      )
      LOCATION ('foo.dat'));

正在创建表emp_load,但是select语句失败并显示以下错误消息。 执行select * from emp_load时出现错误消息:

ORA-29913: error in executing ODCIEXTTABLEFETCH callout
ORA-29400: data cartridge error
KUP-04018: <b>partial record at end of file C:\oracle\foo.dat</b>
29913. 00000 -  "error in executing %s callout"
*Cause:    The execution of the specified callout caused an error.
*Action:   Examine the error messages take appropriate action.

它唯一有效的时间是我制作foo.dat 1行(如下所示)并将FIXED长度更改为19-

Alvin  Tolliver1976KennethBaer    1963Mary   Dube    1973

这似乎表明我在换行字符方面做错了,但我无法弄清楚是什么。

任何帮助将不胜感激。提前谢谢!

2 个答案:

答案 0 :(得分:0)

您在多行数据文件的最后一行之后缺少换行符。即你的最后一行长度是19个字节而不是20个字节。您可以检查数据文件的大小 - 它应该是3 * 20 = 60字节。

当您更改数据文件以将所有数据放在一行中并使用RECORDS FIXED 19时,一切都很好,因为现在不需要新行。

答案 1 :(得分:0)

我找到了答案..

文档说FIXED在结尾处假定换行符。

在Windows中,换行符(\ r \ n)占用2个字节。
因此,在Windows中,传递给FIXED的长度应为=字段总长度+ 2
在Unix中,它应该是=字段的总长度+ 1

我在Windows Vista计算机上安装了Oracle 11g。 所以21是总长度而不是20。

文档中的示例可能是针对新行使用1字节(\ n)

的Unix

因此,如果在Windows上安装Oracle 11g,这是正确的代码 -

CREATE TABLE emp_load (first_name CHAR(15), last_name CHAR(20), year_of_birth CHAR(4))
  ORGANIZATION EXTERNAL (TYPE ORACLE_LOADER DEFAULT DIRECTORY filesdir
                         ACCESS PARAMETERS (RECORDS FIXED 21 FIELDS 
                                              (first_name CHAR(7),
                                               last_name CHAR(8),
                                               year_of_birth CHAR(4)))
                         LOCATION ('info1.dat'));

感谢ypercube提供替代解决方案。我赞成你的建议。 (ypercube建议使用DELIMITED BY NEWLINE提供了一种替代方案,实际上是一种更简单的解决方案。但我想发布上述内容,因为我认为对于尝试使用Oracle文档中的示例进行FIXED的人来说这将是有用的。)