данные не заполняются из загрузчика SQL - PullRequest
1 голос
/ 01 февраля 2012

У меня есть контрольный файл loader.ctl в 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 )

emp1 таблицауже присутствует в базе данных и в test.csv

есть 9 записей * Я выполнил loader.ctl из sqlldr:

enter image description here

Теперь, когда я проверяюв базе данных я не нахожу записей в emp1 ... почему это так?Почему после фиксации данные не заносятся в таблицу?

1 Ответ

8 голосов
/ 02 февраля 2012

Во-первых, вы не указали файл журнала, что означает, что он, вероятно, находится в том же месте, что и ваш файл ctl, но он также может находиться в каталоге, из которого вы называете SQL * Loader, или в каталоге, в котором находятся данные - в стороне Во избежание путаницы рекомендуется вызывать SQL * Loader из того же места, где хранится файл ctl. Ищите его и связанный с ним плохой файл.

Я бы всегда в явном виде указывал местоположение логов и плохих файлов - и, если необходимо, сбрасывал файл - либо в командной строке, либо в файле 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 . Можно достичь точки фиксации, когда все загружается до появления ошибок; то есть вы ничего не делаете.

Пункт 2 - наиболее вероятная причина вашей проблемы. Загляните в файл журнала, и он должен сообщить вам, не обязательно очень полезным способом, почему у вас есть ошибки. Неверный файл содержит все данные, которые не были загружены, и вы можете проверить их по журналу.

Существует множество причин, по которым может возникнуть вторая, поэтому вот список вещей, которые могут пойти не так с SQL * Loader:

  1. Ваши столбцы ctl и столбцы таблицы не называются точно одинаковыми именами.
  2. Ваш файл не существует.
  3. Ваша таблица не существует.
  4. В конце файла есть разделитель, что означает, что вам нужно добавить опцию TRAILING NULLCOLS.
  5. У вас новая строка в середине строки - у вас большие проблемы. Вам нужно будет задать еще один вопрос с полным описанием ctl и таблиц вместе с образцами данных.
  6. Один из столбцов в вашей таблице - это тип данных date. Поскольку каждая часть данных в CSV по определению является строкой SQL * Loader не может превратить это в дату. Я собираюсь предположить, что это hiredate, которое в файле ctl станет hiredate "to_date(:hiredate,'yyyy/mm/dd')", где yyyy/mm/dd изменяется на любой необходимый вам формат даты. Смотрите здесь для хорошего списка. Конечно, вы всегда можете поменять этот столбец на символ и заняться трансформацией позже.
  7. Один из столбцов в вашей таблице - это тип данных числа, и вы пытаетесь загрузить в него не число. Извините, в этом случае вам нужно изменить тип данных вашего столбца на символ.
  8. Один из столбцов в вашей таблице - это число, и вы пытаетесь вставить в него отформатированные числа. Помните, что запятые и десятичные точки не являются числом, в этом случае вы можете использовать функцию to_number: sal "to_number(:sal,'999.99')". Как и в случае с датами, вы всегда можете поменять этот столбец на символ и заняться преобразованием позже.
  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.

С моей головы это большая часть того, что может пойти не так с таким простым грузом, как ваш.

Теперь совет. Укажите . Это так просто. Если вы не воспользуетесь чрезвычайно мощной природой 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

...