美文网首页
使用UTL_FILE写超过32k的数据时报错 ORA-29285

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

作者: 马云生 | 来源:发表于2021-12-30 10:48 被阅读0次

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

       在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

          本文链接:https://www.haomeiwen.com/subject/loriqrtx.html