如何解决自动 CSV 文件生成,在 Oracle 10g 的两个标题级别具有不同列数的标题
我们有一个使用 Oracle 10g R. 10.2.0.4.0 的应用程序。我需要创建一个过程,将给定查询的数据导出到特定布局的 CSV 文件中,以便可以将其导入到另一个应用程序中。
我发现以下链接对我帮助很大。此过程使用 utl_file
并允许我将我需要的查询放在 l_query
字段中。
我需要生成的文件结构如下:
Title;9999
FIELD1;FIELD2;FIELD3;FIELD4;FIELD5
1234;30032021;0400;093000;123000
1235;30032021;0400;133000;183000
我创建了两个级别的标题,一个是为具有两个字段的文件添加标题,另一个是应用程序将加载的数据列的标题。我使用 UNION ALL
实现了这一点。但是,我发现了两个我无法解决的问题:
-
我无法从查询块中删除标题
-
当我使用
UNION ALL
时,第一个阻塞查询迫使我拥有在以下查询中生成信息所需的字段数(五个字段),因此该文件是用两个标头生成,第二个用我需要删除的三个;;;
生成。标题;9999;'';'';''; --我需要删除这个标题 标题;9999; ; ; --我需要去掉三个“;;;” 字段 1;字段 2;字段 3;字段 4;字段 5 1234;08042021;123;224130;044130 1235;08042021;123;224130;044130 1236;08042021;123;224130;044130
这是我用我在变量 l_query
中创建的查询改编的过程。
create or replace procedure dump_table_to_csv(p_dir in varchar2,p_filename in varchar2 )
is
l_output utl_file.file_type;
l_theCursor integer default dbms_sql.open_cursor;
l_columnValue varchar2(4000);
l_status integer;
l_query varchar2(4000)
default
'SELECT ''Title'' AS "Title",''9999'' AS "9999",'' '','' '' from DUAL
UNION ALL
SELECT TO_CHAR(''FIELD1'') AS FIELD1,TO_CHAR(''FIELD2'') AS FIELD2,TO_CHAR(''FIELD3'') AS FIELD3,TO_CHAR(''FIELD4'') AS FIELD4,TO_CHAR(''FIELD5'') AS FIELD5 FROM DUAL
UNION ALL
SELECT
TO_CHAR(''9999'') AS FIELD1,TO_CHAR(SYSDATE,''DDMMYYYY'') AS FIELD2,''123'' AS FIELD3,LPAD(TO_CHAR(SYSDATE,''HH24MISS''),6,0) AS FIELD4,LPAD(TO_CHAR(SYSDATE + INTERVAL ''6:00'' HOUR TO MINUTE,0) AS FILED5
FROM DUAL';
l_colCnt number := 0;
l_separator varchar2(1);
l_descTbl dbms_sql.desc_tab;
begin
l_output := utl_file.fopen( p_dir,p_filename,'w',4000 );
execute immediate 'alter session set nls_date_format=''DD-MM-YYYY HH24:MI:SS'' ';
dbms_sql.parse( l_theCursor,l_query,dbms_sql.native );
dbms_sql.describe_columns( l_theCursor,l_colCnt,l_descTbl );
for i in 1 .. l_colCnt loop
utl_file.put( l_output,l_separator || '' || l_descTbl(i).col_name || ';' );
dbms_sql.define_column( l_theCursor,i,l_columnValue,4000 );
l_separator := '';
end loop;
utl_file.new_line( l_output );
l_status := dbms_sql.execute(l_theCursor);
while ( dbms_sql.fetch_rows(l_theCursor) > 0 ) loop
l_separator := '';
for i in 1 .. l_colCnt loop
dbms_sql.column_value( l_theCursor,l_columnValue );
utl_file.put( l_output,l_separator || l_columnValue );
l_separator := ';';
end loop;
utl_file.new_line( l_output );
end loop;
dbms_sql.close_cursor(l_theCursor);
utl_file.fclose( l_output );
execute immediate 'alter session set nls_date_format=''dd-MON-yy'' ';
exception
when others then
execute immediate 'alter session set nls_date_format=''dd-MON-yy'' ';
raise;
end;
/
EXEC dump_table_to_csv('MY_DIRECTORY','file_to_export.csv' );
谁能帮我解决这个问题,或者告诉我一些其他方法来实现我的目标,并以正确的结构生成这个文件?
解决方法
由于第一个标题行似乎不依赖于查询的结构,所以我只使用一个 utl_file.put_line
将其先打印出来,而 Tom 的其余过程基本保持不变
create or replace procedure dump_table_to_csv(p_dir in varchar2,p_filename in varchar2 )
is
l_output utl_file.file_type;
l_theCursor integer default dbms_sql.open_cursor;
l_columnValue varchar2(4000);
l_status integer;
l_query varchar2(4000) :=
q'{SELECT
TO_CHAR(''9999'') AS FIELD1,TO_CHAR(SYSDATE,''DDMMYYYY'') AS FIELD2,'123' AS FIELD3,LPAD(TO_CHAR(SYSDATE,'HH24MISS'),6,0) AS FIELD4,LPAD(TO_CHAR(SYSDATE + INTERVAL '6:00' HOUR TO MINUTE,0) AS FILED5
FROM DUAL}';
l_colCnt number := 0;
l_separator varchar2(1);
l_descTbl dbms_sql.desc_tab;
begin
l_output := utl_file.fopen( p_dir,p_filename,'w',4000 );
execute immediate 'alter session set nls_date_format=''DD-MM-YYYY HH24:MI:SS'' ';
dbms_sql.parse( l_theCursor,l_query,dbms_sql.native );
dbms_sql.describe_columns( l_theCursor,l_colCnt,l_descTbl );
utl_file.put_line( 'Title;9999' );
for i in 1 .. l_colCnt loop
utl_file.put( l_output,l_separator || '' || l_descTbl(i).col_name || ';' );
dbms_sql.define_column( l_theCursor,i,l_columnValue,4000 );
l_separator := '';
end loop;
utl_file.new_line( l_output );
l_status := dbms_sql.execute(l_theCursor);
while ( dbms_sql.fetch_rows(l_theCursor) > 0 )
loop
l_separator := '';
for i in 1 .. l_colCnt loop
dbms_sql.column_value( l_theCursor,l_columnValue );
utl_file.put( l_output,l_separator || l_columnValue );
l_separator := ';';
end loop;
utl_file.new_line( l_output );
end loop;
dbms_sql.close_cursor(l_theCursor);
utl_file.fclose( l_output );
execute immediate 'alter session set nls_date_format=''dd-MON-yy'' ';
exception
when others then
execute immediate 'alter session set nls_date_format=''dd-MON-yy'' ';
raise;
end;
/
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。