简体   繁体   English

ORA-29285错误使用过程将数据从oracle数据库导出到CSV文件时

[英]ORA-29285 error While exporting data from oracle database to CSV file using procedure

I have a problem here while exporting data from oracle database to CSV file using a procedure. 我在使用过程将数据从oracle数据库导出到CSV文件时遇到问题。 While exporting data, sometimes the CSV file is getting truncated and the error it shows is " ORA-29285 - File write error ". 导出数据时,有时CSV文件被截断,并且显示的错误是“ ORA-29285-文件写入错误 ”。 The problem here is the file is getting truncated not all the times but randomly. 这里的问题是文件并非总是被截断,而是被随机截断。

Edit : Below is the chunk of code I used in my procedure 编辑 :以下是我在过程中使用的代码块

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);`

I am pulling my hair to trace out the reason. 我拉着头发找出原因。 Can someone help me out ? 有人可以帮我吗 ?

One way to get this error is to open the file with a certain maximum line size - possibly the default 1024 - and then try to write a single line to that file which is longer than that. 发生此错误的一种方法是,以一定的最大行大小( 可能是默认的1024)打开文件,然后尝试向该文件中写入比这更长的一行。

In your case you don't seem to be doing that, as you open it with 4096 and your lines are all (apparently) shorter than that. 在您的情况下,您似乎没有这样做,因为您使用4096打开它,并且行(显然)都比该行短。

So you may be hitting the 32k limitation : 因此,您可能会遇到32k的限制

The maximum size of the buffer parameter is 32767 bytes unless you specify a smaller size in FOPEN. 缓冲区参数的最大大小为32767字节,除非您在FOPEN中指定了较小的大小。 If unspecified, Oracle supplies a default value of 1024. The sum of all sequential PUT calls cannot exceed 32767 without intermediate buffer flushes. 如果未指定,则Oracle提供默认值1024。 在不进行中间缓冲区刷新的情况下,所有顺序PUT调用的总和不能超过32767。

You don't seem to be doing any flushing. 您似乎没有进行任何冲洗。 You could change your put_line call to auto-flush: 您可以将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);

or keep a counter in your loop and manually flush every 100 lines (or whatever number works and is efficient for you). 或在您的循环中保留一个计数器,然后每100行手动刷新一次(或任何有效且对您而言有效的行)。

As noted in the documentation : 如文档中所述

If there is buffered data yet to be written when FCLOSE runs, you may receive WRITE_ERROR when closing a file. 如果在FCLOSE运行时尚有待写入的缓冲数据,则在关闭文件时可能会收到WRITE_ERROR。

You aren't flushing before you close, so adding an explicit flush - even if you have autoflush set to true - might also help avoid this, at least if the exception is being thrown by the fclose() call rather than by put_line() : 您在关闭之前不会进行刷新,因此,即使将autoflush设置为true,添加显式刷新也可能有助于避免这种情况,至少在fclose()调用而不是put_line()抛出异常的情况下:

...
end loop;
utl_file.fflush(conn);
utl_file.fclose(conn);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM