我在使用过程将数据从oracle数据库导出到CSV文件时遇到问题。导出数据时,有时CSV文件会被截断,显示的错误是“ ORA-29285 - 文件写入错误”。这里的问题是文件不是一直被截断而是随机截断。
编辑:下面是我在我的程序中使用的代码块
conn := utl_file.fopen('sample_directory','output.csv','W',4096);
for i in (select * from per_data)
loop
utl_file.put_line(conn,i.name||','||i.sub||','||to_char(i.start_date,'dd-mon-yy')||','||to_char(i.expire_date,'dd-mon-yy')||','||i.loc||CHR(13));
end loop;
utl_file.fclose(conn);`
我正在拉我的头发以找出原因。有人可以帮助我吗?
答案 0 :(得分:0)
获取此错误的一种方法是打开具有特定最大行大小的文件 - possibly the default 1024 - 然后尝试将一行写入该文件,该行长于该文件。
在你的情况下,你似乎没有这样做,因为你用4096打开它,你的线条(显然)比那些短。
所以你可能正在点击the 32k limitation:
除非在FOPEN中指定较小的大小,否则缓冲区参数的最大大小为32767字节。如果未指定,则Oracle提供默认值1024. 所有顺序PUT调用的总和不能超过32767而不进行中间缓冲区刷新。
你似乎没有做任何潮红。您可以将put_line
调用更改为自动刷新:
utl_file.put_line(conn,
i.name||','||i.sub||','||to_char(i.start_date,'dd-mon-yy')
||','||to_char(i.expire_date,'dd-mon-yy')||','||i.loc||CHR(13),
true);
或在你的循环中保留一个计数器,并且每100行manually flush(或任何数字起作用并且对你有效)。
As noted in the documentation:
如果在FCLOSE运行时仍有待写入的缓冲数据,则在关闭文件时可能会收到WRITE_ERROR。
在关闭之前你不会刷新,所以添加一个显式刷新 - 即使你将autoflush设置为true - 也可能有助于避免这种情况,至少如果fclose()
引发了异常打电话而不是put_line()
:
...
end loop;
utl_file.fflush(conn);
utl_file.fclose(conn);