Ошибка при экспорте данных CLOB более 32 КБ с использованием UTL_FILE - PullRequest
0 голосов
/ 03 октября 2018

Я использую функцию EXPORT_TABLE_TO_CSV_FILE для экспорта данных CLOB в формате CSV, вызывая их через указанные ниже входные параметры, но получая исключение, когда длина всех столбцов> 32 КБ (предел utl_file).

Как я могу экспортировать данные> 32 КБ?


Сообщенная ошибка

ORA-29285: ошибка записи файла ORA-06512: at "SCOTT.EXPORT_TABLE_TO_CSV_FILE ", строка 105


Вызов proc

DECLARE
 l_sql dbms_sql.varchar2a;
 l_cnt integer;
BEGIN
 l_sql(1) := 'select er.id,ee.creationdate,eo.NAME,replace(replace(er.VALUE,chr(10),''''),chr(13),'''') as value from overlay ee, model eo,result er where ee.model=eo.id and ee.CASEID=''289342337'' and er.OVERLAYD=ee.id';
 l_cnt    := export_table_to_csv_file
             (
                  l_sql,
                  '|',
                  'DUMP_DIR',
                  'csvsample4.csv',
                  TRUE
             );
END;

EXPORT_TABLE_TO_CSV_FILE

create or replace FUNCTION  EXPORT_TABLE_TO_CSV_FILE
(
       p_query     in dbms_sql.varchar2a,
       p_separator in varchar2 default ',',
       p_dir       in varchar2,
       p_filename  in varchar2,
       p_is_head   in boolean default false
)
RETURN NUMBER
is
       l_output        utl_file.file_type;
       l_theCursor     integer default dbms_sql.open_cursor;
       l_columnValue   varchar2(4000);
       l_columnValClob clob;
       l_status        integer;
       l_colCnt        number default 0;
       l_separator     varchar2(10) default '';
       l_cnt           number default 0;
       l_col_desc      dbms_sql.desc_tab;
       l_offset        integer;
BEGIN
       dbms_sql.parse
       (
           l_theCursor
         , p_query
         , p_query.first
         , p_query.last
         , true
         , dbms_sql.native
       );

       dbms_sql.describe_columns
       (
           l_theCursor
         , l_colCnt
         , l_col_desc
       );

       for i in 1 .. l_colCnt loop
           if l_col_desc(i).col_type = 112 then
               dbms_sql.define_column
               (
                   l_theCursor
                 , i
                 , l_columnValClob
               );
          else
               dbms_sql.define_column
               (
                   l_theCursor
                 , i
                 , l_columnValue
                 , 4000
               );
          end if;
       end loop;

       l_status := dbms_sql.execute(l_theCursor);
       if dbms_sql.fetch_rows(l_theCursor) > 0 then
               l_output := utl_file.fopen( p_dir, p_filename, 'w', 32767 );
               if p_is_head then
                       for i in 1..l_col_desc.count
                       loop
                               utl_file.put(l_output, l_separator || l_col_desc(i).col_name);
                               l_separator := p_separator;
                       end loop;
                       utl_file.new_line( l_output );
               end if;

               loop
                       l_separator := '';
                       for i in 1 .. l_colCnt
                       loop
                           if l_col_desc(i).col_type = 112
                           then
                              l_offset := 1;
                              dbms_sql.column_value
                              (
                                   l_theCursor
                                 , i
                                 , l_columnValClob
                              );
                              utl_file.put( l_output, l_separator );

                              loop
                                    l_columnValue := dbms_lob.substr(l_columnValClob, 4000, l_offset);
                                   -- dbms_output.put_line(l_columnValue);
                                    l_offset := l_offset + 4000;
                                    utl_file.put( l_output, l_columnValue);
                                    exit when trim(l_columnValue) is null;
                               end loop;
                           else
                              dbms_sql.column_value
                              (
                                   l_theCursor
                                 , i
                                 , l_columnValue
                              );
                              utl_file.put( l_output, l_separator ||  l_columnValue );
                           end if;

                           l_separator := p_separator;
                       end loop;

                       utl_file.new_line( l_output );
                       l_cnt := l_cnt+1;

                       exit when ( dbms_sql.fetch_rows(l_theCursor) <= 0 );
               end loop;
       end if;
       dbms_sql.close_cursor(l_theCursor);
       utl_file.fclose( l_output );
       return l_cnt;
END;
...