使用UTL_FILE写超过32k的数据时报错 ORA-29285

   最近项目上有位同事遇到这样一个问题

   在PLSQL中用UTL_FILE的包写文件时,由于一行的数据过大(超过Vachar2的定义长度32k,也就是32767byte)报错,来求助帮忙想办法解决。(出力的文件是个CSV文件,第一行为行头,后面是数据,行头里都是日语项目名,每个项目名有特别特别多和长)

     刚开始想到,既然是Vachar2的定义长度的限制,能不能把行头分成2行输出,然后输出文件后再把2行行头合并呢,因为这次是一个工具的程序,在plsql中写出CSV文件,然后之后会用VBA程序读入文件内容到Excel的模板里。

     所以想到PLSQL输出文件时先把出2行,再在VBA里合并就好了,可是经过调查发现因为工具太过复杂,如果这个做需要大量的改动工作量。


   后来突然想到既然是Vachar2的定义长度的限制,能不能把头行内容改成CLOB类型输出到一行再输出数据呢,试验了下这样改动可以减少大量的工具改造。做法如下:


DECLARE

  l_directory VARCHAR2(20) := 'u01/path';--这里是文件输出路径

  l_file_name VARCHAR2(20) := 'test.csv';--这里是文件输出文件

  l_file      utl_file.file_type;

  l_clob  CLOB;--原来出错时用的是VARCHAR2(32767)

  l_len      BINARY_INTEGER ;

  l_pos BINARY_INTEGER ;

  l_buffer VARCHAR2(32767);

  l_amount BINARY_INTEGER ;

BEGIN

l_pos := 1;

l_amount  := 1024;

--此循环只是为了模拟超过32k长的行头,放入l_clob 变量里。

FOR i IN 1 .. 5000

  LOOP

    l_clob := l_clob || '[共通]20kV・30kV力率修正前基本料金';

  END LOOP;

--此处是为了输出行头后换行

l_clob := l_clob||CHR(13)||CHR(10);

--select  dbms_lob.getlength(l_clob) into l_len  from dual;

l_len := dbms_lob.getlength(l_clob);

  --此处不用W方式用WB

  l_file := utl_file.fopen(l_directory, l_file_name, 'wb', 32767);

  WHILE l_pos < l_len LOOP

    dbms_lob.READ(l_clob, l_amount, l_pos, l_buffer);

    utl_file.put_raw(l_file, utl_raw.cast_to_raw(l_buffer));

    utl_file.fflush(l_file);

    l_pos := l_pos + l_amount;

  END LOOP;

  utl_file.fclose(l_file);

EXCEPTION

  WHEN OTHERS THEN

    dbms_output.put_line(SQLERRM);

END;

/

你可能感兴趣的:(使用UTL_FILE写超过32k的数据时报错 ORA-29285)