使用UTL_FILE寫超過32k的數(shù)據(jù)時報錯 ORA-29285

? ?最近項目上有位同事遇到這樣一個問題

? ?在PLSQL中用UTL_FILE的包寫文件時,由于一行的數(shù)據(jù)過大(超過Vachar2的定義長度32k,也就是32767byte)報錯,來求助幫忙想辦法解決。(出力的文件是個CSV文件,第一行為行頭,后面是數(shù)據(jù),行頭里都是日語項目名,每個項目名有特別特別多和長)

? ? ?剛開始想到,既然是Vachar2的定義長度的限制,能不能把行頭分成2行輸出,然后輸出文件后再把2行行頭合并呢,因為這次是一個工具的程序,在plsql中寫出CSV文件,然后之后會用VBA程序讀入文件內(nèi)容到Excel的模板里。

? ? ?所以想到PLSQL輸出文件時先把出2行,再在VBA里合并就好了,可是經(jīng)過調(diào)查發(fā)現(xiàn)因為工具太過復雜,如果這個做需要大量的改動工作量。


? ?后來突然想到既然是Vachar2的定義長度的限制,能不能把頭行內(nèi)容改成CLOB類型輸出到一行再輸出數(shù)據(jù)呢,試驗了下這樣改動可以減少大量的工具改造。做法如下:


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;

--此循環(huán)只是為了模擬超過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;

/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容