Внешние таблицы — ошибка «частичная запись в конце файла» при использовании ИСПРАВЛЕНО

#database #oracle #plsql #oracle11g #external-tables

#База данных #Oracle #plsql #oracle11g #внешние таблицы

Вопрос:

Я получаю ошибку «частичная запись в конце файла» при использовании ФИКСИРОВАННОГО параметра с внешними таблицами.

Я использую 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:oraclefoo.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 строку (как показано ниже) и изменил ФИКСИРОВАННУЮ длину на 19-

 Alvin  Tolliver1976KennethBaer    1963Mary   Dube    1973
  

Похоже, это указывает на то, что я делаю что-то не так в отношении символов новой строки, но я не могу понять, что именно.

Любая помощь будет оценена. Заранее спасибо!

Комментарии:

1. Я думаю, вам нужно DELIMITED BY NEWLINE : download.oracle.com/docs/cd/B19306_01/server.102/b14215 /…

2. @ypercude: Боюсь, вы ошиблись. Из спецификации, которую вы связали: предложение FIXED используется для идентификации записей как имеющих фиксированный размер байтов длины. Размер, указанный для ФИКСИРОВАННЫХ записей, должен включать любые символы завершения записи, такие как новые строки. Я думаю, что DDL OP верен.

Ответ №1:

В вашем многострочном файле данных отсутствует символ новой строки после последней строки. Т.е. длина вашей последней строки составляет 19 байт, а не 20 байт. Вы можете проверить размер вашего файла данных — он должен быть 3 * 20 = 60 байт.

Когда вы меняете файл данных, чтобы все данные были в одной строке, и используете RECORDS FIXED 19 все снова хорошо, потому что теперь новая строка не ожидается.

Ответ №2:

Я нашел ответ..

В документации говорится, что FIXED предполагает символ новой строки в конце.

В Windows новая строка (r n) занимает 2 байта.
Итак, в Windows длина, передаваемая в FIXED, должна быть = общая длина полей 2
В Unix это должно быть = общая длина полей 1

Я установил Oracle 11g на свой компьютер с Windows Vista. Таким образом, 21 — это общая длина вместо 20.

Пример в документации, вероятно, был для Unix, который использует 1 байт для перевода строки (n)

Итак, это правильный код, если Oracle 11g установлен в Windows —

СОЗДАЙТЕ ТАБЛИЦУ emp_load (СИМВОЛ first_name(15), символ last_name(20), символ year_of_birth(4))
 ОРГАНИЗАЦИЯ ВНЕШНЯЯ (ТИП ORACLE_LOADER КАТАЛОГ filesdir ПО УМОЛЧАНИЮ
 ПАРАМЕТРЫ ДОСТУПА (ЗАПИСИ ИСПРАВЛЕНЫ В 21 ПОЛЕ 
 (символ first_name(7),
символ last_name(8),
символ year_of_birth(4)))
 МЕСТОПОЛОЖЕНИЕ ('info1.dat'));

Спасибо ypercube за альтернативное решение. Я поддержал ваше предложение. (предложение ypercube использовать РАЗДЕЛИТЕЛЬ новой СТРОКИ предоставило альтернативу, на самом деле более простое решение. Но я хотел опубликовать выше, так как я думаю, что это будет полезно для тех, кто пытается использовать пример из документации Oracle для FIXED.)