2016-09-27 2 views
0

я должен вставить несколько строк в таблицу из файла структурированного как это:Как вставить несколько строк из потока

BANAC2C100017701007_X75 _CA  4X2 CT  MLCR DR  SX  EP  160 E4 

где 4x2, MLCR, 160 Е4 должны быть вставлены в ту же колонку для тот же код BANAC2C100017701007. В качестве примера, таблица должна быть структурирована следующим образом:

enter image description here

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

+0

Можете ли вы использовать sqlldr? Имеют ли данные разделители или являются ли поля фиксированной длины? Или они, по крайней мере, имеют одинаковое количество элементов? –

ответ

0

Это можно сделать с помощью sqlldr. Я сделал некоторые предположения, но если данные представляют собой одну строку на строку, как вы описали выше, с тем же количеством элементов строки, правильно сконструированный управляющий файл с несколькими операторами «в таблицу» может писать разные части одной строки данных как несколько строк в одну и ту же таблицу.

Контроль файла:

LOAD DATA 
infile "file.dat" 
TRUNCATE 
INTO TABLE data_table 
(entirerow BOUNDFILLER char(4000) 
,code expression "regexp_substr(:entirerow, '(.*?)(_)', 1, 1, NULL, 1)" 
,desc expression "regexp_substr(:entirerow, '(.*?)(+)', 1, 3, NULL, 1)" 
) 
INTO TABLE data_table 
(entirerow BOUNDFILLER position(1) char(4000) 
,code expression "regexp_substr(:entirerow, '(.*?)(_)', 1, 1, NULL, 1)" 
,desc expression "regexp_substr(:entirerow, '(.*?)(+)', 1, 5, NULL, 1)" 
) 
INTO TABLE data_table 
(entirerow BOUNDFILLER position(1) char(4000) 
,code expression "regexp_substr(:entirerow, '(.*?)(_)', 1, 1, NULL, 1)" 
,desc expression "regexp_substr(:entirerow, '(.*?)(+)', 1, 9, NULL, 1) || ' ' || 
        regexp_substr(:entirerow, '(.*?)(+|$)', 1, 10, NULL, 1)" 
) 

Пару вещей отметить:

Поскольку нет никаких ограничителей, и ничего не указано, то вся строка будет прочитана в первом поле «EntireRow» , Поскольку это не столбец в таблице, и он определен как BOUNDFILLER, он «запоминается» для использования позже.

Следующее поле «код» находится в файле управления. Поле данных не существует, но sqlldr находит, что он соответствует столбцу в таблице, и видит, что это выражение, поэтому оно применяет выражение с намерением поместить результат в столбец. Выражение использует REGEXP_SUBSTR против запоминающегося BOUNDFILLER, чтобы вырезать нужные нам части. Для кода введите символы до, но не включая первый символ подчеркивания. Для desc получите третий набор символов, за которым следует одно или несколько пробелов (но не пробелы).

Для второй логической строки нам нужно переместить логический указатель назад в начало строки, прочитанной так, чтобы sqlldr мог повторно обрабатывать. В противном случае логический указатель находится в конце данных, и ничего не будет возвращено. Это делается с параметром «позиция», указанным в определении «entirerow» второго и третьего «в таблицу». Последняя «в таблицу» следует предыдущей парадигме, просто получая 9-е и 10-е поля и объединяя их вместе. Я решил сделать это вместо того, чтобы придумать другое регулярное выражение, чтобы оно соответствовало другим полям, плюс, если вы хотите изменить его в будущем, будет легче следовать.

Как вы можете видеть, что это работает и многоразовые:

SQL> select code, desc 
    from data_table; 

CODE      DESC 
------------------------- ------------- 
BANAC2C100017701007  4X2 
BANAC2C100017701007  MLCR 
BANAC2C100017701007  160 E4 

Возможные нюанс: каждая строка сканируется в 3 раза, а регулярное выражение звонки стоят дорого, так в зависимости от объема данных, которые нужно загрузить этот не может быть приемлемым решением для вашей ситуации.

Смежные вопросы