Oracle UTL_文件使用附加模式创建重复的头
如何在UTL_文件包中使用“A”ppend模式,但只创建一个头(不重复)?可能吗?我正在追加数据,但每次追加数据时,都会创建重复的标题 我的代码:Oracle UTL_文件使用附加模式创建重复的头,oracle,plsql,utl-file,Oracle,Plsql,Utl File,如何在UTL_文件包中使用“A”ppend模式,但只创建一个头(不重复)?可能吗?我正在追加数据,但每次追加数据时,都会创建重复的标题 我的代码: CREATE OR REPLACE PROCEDURE p_test AS CURSOR c_test IS select blah, blah from dual; v_file UTL_FILE.FILE_TYPE; v_header varchar2(25); BEGIN v_file := UTL_FILE.FOPEN(loc
CREATE OR REPLACE PROCEDURE p_test AS
CURSOR c_test IS
select blah, blah from dual;
v_file UTL_FILE.FILE_TYPE;
v_header varchar2(25);
BEGIN
v_file := UTL_FILE.FOPEN(location => 'my_dir',
filename => 'filetest09102019.csv',
open_mode => 'A',
max_linesize => 32767);
If file exists = 0 then --using fgetattr; if I use 1, repeating headers will print
v_header := 'col1, col2, col3';
utl_file.put_line (v_file, v_header);
Else null; end if; --unfortunately headers did not print at all when false/0
FOR cur_rec IN c_test LOOP
UTL_FILE.PUT_LINE(v_file, data from c_test );
END LOOP;
UTL_FILE.FCLOSE(v_file);
EXCEPTION
WHEN OTHERS THEN
UTL_FILE.FCLOSE(v_file);
END;
如果多次调用此过程,则每次调用该过程时都会将头追加到文件中 您可以先检查文件是否存在,然后再追加标头,例如,使用fgetattr检测是否要追加文件
或者,修改您的代码,使其只调用一次过程并一次性写入所有数据,而不附加任何内容。您可以通过一些设计来解决这个问题。目前,您有一个过程,它以追加模式打开文件,将头写入其中,然后将数据写入其中。您需要的是打开文件的子程序。这一程序将是有效的 实现以下逻辑:
严格来说,
open\u file()
在本例中不需要私有过程。但一般来说,我认为在单独的过程中隐藏底层内容是一种好的做法,因为这样可以使代码的主体更易于阅读。此外,我们通常希望在多个位置(针对多种类型的文件)执行此操作,因此便于封装。谢谢,Jeffrey。不幸的是,“文件存在”对我不起作用。该文件每天生成一次,带有时间戳——如果该文件已经存在,而不是文件生成本身的第一次运行,它可能会工作(对不起,我在最初的帖子中没有提到它)。除非我的逻辑是错误的(参见上面修改的代码)。我不能使用“write”选项,因为软件正在调用它,需要append选项,否则它将无法工作:(这没有意义-您是否在使用fopen创建文件后立即检查该文件是否存在?在打开该文件进行附加之前,您应该检查该文件是否存在。如果您的文件有多个标题,您必须以某种方式为同一文件名多次调用此过程。我看不到任何其他可能发生的情况,除非还有其他的代码你没有给我们看。我的天,你说得对!!谢谢,它现在可以工作了!谢谢,还没有试过,但这也有道理:D
CREATE OR REPLACE PROCEDURE p_test AS
CURSOR c_test IS
select blah, blah from dual;
v_file UTL_FILE.FILE_TYPE;
v_header varchar2(25) := 'col1, col2, col3';
function open_file (p_filename in varchar2
, p_dirname in varchar2
, p_header in varchar2
)
return UTL_FILE.FILE_TYPE
is
fh UTL_FILE.FILE_TYPE;
l_fexists boolean;
l_flen number;
l_bsize number;
l_res number(1);
begin
utl_file.fgetattr(upper(p_DirName), p_FileName, l_fexists, l_flen, l_bsize);
if not l_fexists then
fh := UTL_FILE.FOPEN(location => p_DirName,
filename => p_FileName,
open_mode => 'W',
max_linesize => 32767);
utl_file.put_line (fh, p_header);
utl_file.fclose(fh);
end if;
fh := UTL_FILE.FOPEN(location => p_DirName,
filename => p_FileName,
open_mode => 'A',
max_linesize => 32767);
return fh;
end open_file;
BEGIN
v_file := open_file 'my_dir', 'filetest09102019.csv', v_header);
FOR cur_rec IN c_test LOOP
UTL_FILE.PUT_LINE(v_file, data from c_test );
END LOOP;
UTL_FILE.FCLOSE(v_file);
EXCEPTION
WHEN OTHERS THEN
UTL_FILE.FCLOSE(v_file);
END;