2015-03-05 4 views
0

У меня есть плоский файл внутри поля clob и структура плоского файла, как показано ниже. и плоские файлы содержатx миллионов записей.Нужно записывать данные файла CLOB в таблицу ORACLE с PLSQL

col1,col2,col3,col4,col5,col6 
A,B,C,,F,D 
1,A,2,B,B,C 

Традиционные способы я не могу использовать как

1-выборки данных из CLOB в Excel или что-то и загрузить данные в таблицу с SQL-загрузчика.

2-в настоящее время я могу напечатать файл clob с кодом ниже.

OPEN c_clob; 
LOOP 
FETCH c_clob INTO c; 
EXIT 
WHEN c_clob%notfound; 
printout(c); 

но проблема в коде выше, если я использую это переменный в вставное заявление, то это дает ошибку в связи с CLOB для вставки ВДПА.

INSERT INTO Table1 VALUES(c); 
commit; 

ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 848239, maximum: 4000) 

Есть ли еще одна опция для обработки огромного плоского файла из поля clob и сбрасывания в таблицу.

В настоящее время я использую ниже код

declare nStartIndex number := 1; nEndIndex number := 1; nLineIndex number := 0; vLine varchar2(2000); cursor c_clob is select char_data from clob_table where seq=1022; c clob; procedure printout (p_clob in out nocopy clob) is offset number := 1; amount number := 32767; amount_last number := 0; len number := dbms_lob.getlength(p_clob); lc_buffer varchar2(32767); line_seq pls_integer := 1; -- For UNIX type file - replace CHR(13) to NULL CR char := chr(13); --CR char := NULL; LF char := chr(10);
nCRLF number; sCRLF varchar2(2); b_finish boolean := true; begin sCRLF := CR || LF; nCRLF := Length(sCRLF); if (dbms_lob.isopen(p_clob) != 1) then dbms_lob.open(p_clob, 0); end if; amount := instr(p_clob, sCRLF, offset); while (offset < len) loop -- For without CR/LF on end file If amount < 0 then amount := len - offset + 1; b_finish := false; End If; dbms_lob.read(p_clob, amount, offset, lc_buffer); If b_finish then lc_buffer := SUBSTR(lc_buffer,1,Length(lc_buffer)-1);
End If; if (line_seq-1) > 0 then amount_last := amount_last + amount; offset := offset + amount; else amount_last := amount; offset := amount + nCRLF; end if; amount := instr(p_clob, sCRLF, offset); amount := amount - amount_last; dbms_output.put_line('Line #'||line_seq||': '||lc_buffer); line_seq := line_seq + 1; end loop; if (dbms_lob.isopen(p_clob) = 1) then dbms_lob.close(p_clob); end if; exception when others then dbms_output.put_line('Error : '||sqlerrm); end printout; begin open c_clob; loop fetch c_clob into c; exit when c_clob%notfound; printout(c); end loop; close c_clob; end;

Здесь линия printout(c); (четвёртая последняя строка в коде) показывает мне линию данных CLOB по линии недо буфера получает переполнение.

Ожидаемый результат: Для чтения данных из плоского файла clob и вставки строк в столбец столбца мудрый. Этого я пытаюсь достичь. Ограничения - это плоские файлы, содержащие миллионы записей.

+0

не уверен, что я понимаю ... у вас есть CLOB, содержащий данные CSV, и вы хотите преобразовать это в отдельные столбцы в другую таблицу? Или просто скопировать весь CLOB в другую таблицу? Каким типом данных является ваш столбец в таблице «Таблица1» и какой запрос находится за курсором 'c_clob'? –

+0

Да, Clob содержит файл csv. Я хочу преобразовать это в отдельные столбцы в другую таблицу. 'CURSOR c_clob IS SELECT char_data FROM table;' – user1782212

+0

Затем вам нужно будет читать CLOB по очереди (см. [Пакет 'dbms_lob'] (https://docs.oracle.com/cd/E18283_01/ appdev.112/e16760/d_lob.htm)), а затем разделите каждую из этих строк на токены на основе разделителя запятой. Есть много примеров обеих частей, вам просто нужно попытаться собрать их вместе. –

ответ

0

я использую что-то вроде этого

... 
select * into ifile from clob_table where ...; 
file_length := dbms_lob.getlength (ifile.char_data); 
p_start :=1; 
while p_start<>0 loop 
    end_pos := dbms_lob.instr (ifile.char_data, chr (10), p_start); 
    if end_pos > 0 then 
     strRow := dbms_lob.substr(ifile.char_data, least (end_pos - p_start, 240), p_start),chr (13)||chr (10); 
     p_start := end_pos + 1; 
     tabRow := strRow2tabRow(strRow); 
    else 
     strRow := dbms_lob.substr (ifile.char_data, file_length - p_start + 1, p_start); 
     p_start := 0; 
     tabRow := strRow2tabRow(strRow); 
    end if; 

insert into myTable values tabRow; 
end loop; 
... 

и функции

function strRow2tabRow(strRow varchar2) return myTable%rowtype is 
    tabRow myTable%rowtype; 
begin 
    tabRow.col1:=valueIncolumn(strRow,1); 
    tabRow.col2:=valueIncolumn(strRow,2); 
    ... 
    /*or maybe this may be better for you 
    select * into tabRow from (
     select rownum rn, regexp_substr(strRow,'[^,]+', 1, level) hdn from dual connect by regexp_substr(strRow, '[^,]+', 1, level) is not null 
     ) pivot (max(hdn) for rn in (1, 2, ...)); 
    */  
    return tabRow; 
exception when others then 
    return tabRow; 
end; 

function valueIncolumn(strRow varchar2, pos in number) return varchar2 is 
    ret varchar2(1024); 
begin 
    select hdn into ret from (
     select rownum rn, regexp_substr(strRow,'[^,]+', 1, level) hdn from dual connect by regexp_substr(strRow, '[^,]+', 1, level) is not null 
    ) where rownum=pos; 
    return ret; 
exception when others then 
    return null; 
end;  

надеюсь, это поможет

+0

Не можем ли мы обрабатывать> 32K данные из PLSQL ... Для PLSQL должен быть способ для этого ... Выше метод не работает :(.. Цените всю свою помощь .. – user1782212

+0

@Alex любые другие решения ?? – user1782212

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