Загрузить CSV с помощью SQLLDR (отклонено)

у меня есть CSV-файл. я хочу загрузить содержимое CSV-файла в oracle database with SQLLDR.

Мой SQLLDR

@echo off
sqlldr black@user/password data=D:\csv\data.csv control=D:\ctl\loader.ctl log=D:\ctl    \loader.log bad=D:\ctl\loader.bad
pause

Мой loader.ctl

  OPTIONS (SKIP=1)
    LOAD DATA
    APPEND  
  INTO TABLE data2007
  FIELDS TERMINATED BY ',' TRAILING NULLCOLS
  ( number "TRIM (:number)",
    name "TRIM (:name)",
    total "TRIM (:total)",
  )

Таблица

CREATE TABLE DATA2007 (
    number      VARCHAR2(6),
    name        VARCHAR2(30),
    total       NUMBER NULL,
  )

Мои данные.csv:

Number,name,Total
1,"Marlyn",2000
2,"Bobby",1000
3,"Rina",2000
4,"Robby,Mr",5000
5,"juliet,Mrs",5000

строки 1,2,3 = успешно, но строки 4 и 5 отклонены. Я знаю, в чем проблема, в строках 4 и 5 есть четыре столбца.

  1. Как решить эту проблему?
  2. во время загрузки я могу вставить текущую дату после поля «итого»?

person flyingbird013    schedule 21.08.2013    source источник


Ответы (1)


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

FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS

Это действительно должен быть отдельный вопрос, но для загрузки фиксированного значения вы можете либо установить для столбца значение по умолчанию и вообще не указывать его в управляющем файле, либо при желании использовать предложение DEFAULTIF, если вы иногда хотите его переопределить. ; или проще использовать строку SQL, чтобы получить значение. Изменение определения таблицы, чтобы включить поле load_date (и изменить имя первого столбца с number на id, которое не является зарезервированным словом, и сделать его типом NUMBER):

CREATE TABLE DATA2007 (
  id          NUMBER,
  name        VARCHAR2(30),
  total       NUMBER NULL,
  load_date   DATE
);

Тогда управляющий файл:

OPTIONS (SKIP=1)
  LOAD DATA
  APPEND
INTO TABLE data2007
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS
( id "TRIM (:id)",
  name "TRIM (:name)",
  total "TRIM (:total)",
  load_date "SYSDATE"
)

Запуск этого с исходным файлом данных дает:

Total logical records skipped:          1
Total logical records read:             5
Total logical records rejected:         0
Total logical records discarded:        0

А также:

SELECT * FROM data2007;

        ID NAME                                TOTAL LOAD_DATE
---------- ------------------------------ ---------- -------------------
         1 Marlyn                               2000 2013-08-21 09:37:38
         2 Bobby                                1000 2013-08-21 09:37:38
         3 Rina                                 2000 2013-08-21 09:37:38
         4 Robby,Mr                             5000 2013-08-21 09:37:38
         5 juliet,Mrs                           5000 2013-08-21 09:37:38

5 rows selected.
person Alex Poole    schedule 21.08.2013
comment
Могу ли я отредактировать control.ctl так, чтобы он был ( id TRIM (:id), load_date SYSDATE, name TRIM (:name), total TRIM (:total), ) - person flyingbird013; 25.08.2013
comment
@ flyingbird013 - вам понадобится соответствующее поле в файле данных, содержание почему (если оно не пустое) будет проигнорировано. Если у вас еще нет такого поля, было бы проще оставить его как есть. Порядок полей в управляющем файле не обязательно должен совпадать с порядком в таблице, если это вас беспокоит. (Обрезка числовых полей, вероятно, тоже бессмысленна, не так ли?) - person Alex Poole; 25.08.2013