Как загрузить несовместимый файл CSV, используя загрузчик SQL? - PullRequest
0 голосов
/ 14 января 2019

У меня есть ниже образец файла CSV

,,,Test File,
,todays Date:,01/10/2018,Generation date,10/01/2019 11:20:58
Header 1,Header 2,Header 3,Header 4,Header 5
,My account no,100102GFC,,
A,B,C,D,E
A,B,C,D,E
A,B,C,D,E

Ниже приведена структура моей таблицы

Todays Date,My account,Header 1,Header 2,Header 3,Header 4,Header 5
01/10/2018,100102GFC,A,B,C,D,E
01/10/2018,100102GFC,A,B,C,D,E
01/10/2018,100102GFC,A,B,C,D,E

У меня проблемы с получением текущей даты из второй строки моего файла и с учетной записью № из 4-й строки файла. Первые четыре строки будут последовательными. Мои фактические данные начинаются с 5-й строки.

Можно ли получить частную информацию из 2-й и 4-й строки и загрузить ее вместе с другими значениями, начиная с 5-й строки? как мы справимся с этим в контрольном файле?

Ответы [ 2 ]

0 голосов
/ 16 января 2019

Распространенным способом обработки нагрузок также является загрузка всех строк в промежуточную таблицу. Например, вы можете создать промежуточную таблицу с 5 столбцами varchar2 (наибольшее количество столбцов в данных). Обрежьте и загрузите все строки как есть в промежуточную таблицу.

enter image description here

Затем создайте сценарий PL / SQL для запуска, который загружает данные из промежуточной таблицы в рабочие таблицы, выполняя проверки и преобразовывая их по пути. Сделайте это хранимой процедурой.

declare
  save_date date;
  save_acct_nbr varchar2(10);
begin

    execute immediate 'truncate table x_test';

    -- Save the file date
    select to_date(col3, 'MM/DD/YYYY')
    into save_date
    from X_TEST_STG
    where col2 = 'todays Date:';

    -- Save the account number
    select col3
    into save_acct_nbr
    from X_TEST_STG
    where col2 = 'My account no';

    insert into x_test
    (select save_date, save_acct_nbr, col1, col2, col3, col4, col5
     from X_TEST_STG
     where col1 is not null
     and col1 != 'Header 1');

    commit;
end;

Бадда Бинг, Бадда Бум!

enter image description here

0 голосов
/ 14 января 2019

Вы можете условно загружать записи в разные таблицы. Таким образом, вы можете достичь этого эффекта:

  • Создание трех промежуточных таблиц: дата загрузки, дата счета и данные загрузки
  • Загрузка записей в соответствующую таблицу
  • Перекрестное объединение результатов для получения результата

Например, создайте эти промежуточные таблицы:

create table t (
  c1 varchar2(1),
  c2 varchar2(1),
  c3 varchar2(1),
  c4 varchar2(1),
  c5 varchar2(1)
);

create table dt (
  load_date date
);

create table act (
  acct# varchar2(20)
);

Затем используйте следующий управляющий файл, чтобы указать, когда загружать какие записи в каждую таблицу:

LOAD DATA
infile *
TRUNCATE 
INTO TABLE dt WHEN (2:13) = 'todays Date:'
FIELDS TERMINATED BY ","
DATE FORMAT "DD/MM/YYYY"
TRAILING NULLCOLS
(
c1 filler, c2 filler, load_date date, c4 filler, c5 filler
)
INTO TABLE act WHEN (2:14) = 'My account no'
FIELDS TERMINATED BY ","
TRAILING NULLCOLS
(
c1 filler position(1:1), c2 filler, acct#, c4 filler, c5 filler
)
INTO TABLE t WHEN (1:1) <> ','
FIELDS TERMINATED BY ","
TRAILING NULLCOLS
(
c1 position(1), c2, c3, c4, c5 
)
BEGINDATA
,,,Test File,
,todays Date:,01/10/2018,Generation date,10/01/2019 11:20:58
Header 1,Header 2,Header 3,Header 4,Header 5
,My account no,100102GFC,,
A,B,C,D,E
A,B,C,D,E
A,B,C,D,E

Предложения when используют позиционную нотацию для проверки заданных символов. Отрегулируйте по необходимости. Заполнитель в предложениях столбца означает игнорирование этого поля.

Теперь загрузите его:

sqlldr userid=chris/chris@db control=sqlldr.ctl

SQL*Loader: Release 12.2.0.1.0 - Production on Mon Jan 14 10:56:40 2019

Copyright (c) 1982, 2017, Oracle and/or its affiliates.  All rights reserved.

Path used:      Conventional
Commit point reached - logical record count 7

Table DT:
  1 Row successfully loaded.

Table ACT:
  1 Row successfully loaded.

Table T:
  3 Rows successfully loaded.

Check the log file:
  sqlldr.log
for more information about the load.

Все, что вам нужно сделать, это соединить их все вместе, чтобы получить желаемый результат:

select * from dt
cross  join act
cross  join t;

LOAD_DATE           ACCT#       C1   C2   C3   C4   C5   
01-OCT-2018 00:00   100102GFC   A    B    C    D    E    
01-OCT-2018 00:00   100102GFC   A    B    C    D    E    
01-OCT-2018 00:00   100102GFC   A    B    C    D    E 

Это немного грязно. Если вы можете перенести файл на сервер базы данных, вам будет проще использовать внешние таблицы.

...