现在的位置: 首页 > 综合 > 正文

Oracle 查询结果导出为csv格式

2017年11月11日 ⁄ 综合 ⁄ 共 3721字 ⁄ 字号 评论关闭

oracle plussql语句导出查询结果,导出文件格式为csv格式

 预备知识:

1.  Oracle的存储过程知识

2.  Oracle Utl_filedirectory知识

3.   隐含知识点:plussql中表名用变量代替如何实现

假设要执行查询语句: select* from student; 
这里想将student 用变量代理,那怎么处理呢?

定义一个变量 v_tablename

student表名赋值给变量 v_tablename:=student

拼接sql语句: v_sql=select * from
||v_tablename;

执行sql语句:execute immediate v_sql;

所有代码块如下

declare

 v_tablename varchar2(100);

 v_sql varchar2(100);

begin

 v_tablename:='student';

 v_sql:='select * from '||v_tablename;

 execute immediate v_sql;

 end;

SQL_TO_CSV
存储过程

从网络上找来一个存储过程,实现了将查询结果导出生成csv文件,

存储过程代码如下

create or replace procedure outtocsv(P_QUERY IN VARCHAR2,P_DIRIN 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_COLCNT NUMBER := 0;
L_SEPARATOR VARCHAR2(1);
L_DESCTBL DBMS_SQL.DESC_TAB;
P_MAX_LINESIZE NUMBER := 32000;
begin
--OPEN FILE
L_OUTPUT := UTL_FILE.FOPEN(P_DIR, P_FILENAME, 'W', P_MAX_LINESIZE);

--DEFINE DATE FORMAT
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_DATE_FORMAT=''YYYY-MM-DDHH24:MI:SS''';

--OPEN CURSOR
DBMS_SQL.PARSE( L_THECURSOR, P_QUERY, DBMS_SQL.NATIVE );
DBMS_SQL.DESCRIBE_COLUMNS( L_THECURSOR, L_COLCNT, L_DESCTBL );

--DUMP TABLE COLUMN NAME
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 );

--EXECUTE THE QUERY STATEMENT
--L_STATUS := DBMS_SQL.EXECUTE(L_THECURSOR);

--DUMP TABLE COLUMN VALUE
WHILE ( DBMS_SQL.FETCH_ROWS(L_THECURSOR) > 0 ) LOOP
L_SEPARATOR := '';
FOR I IN 1 .. L_COLCNT LOOP
DBMS_SQL.COLUMN_VALUE( L_THECURSOR, I, L_COLUMNVALUE );
UTL_FILE.PUT( L_OUTPUT, L_SEPARATOR || '"' ||
TRIM(BOTH ' ' FROM REPLACE(L_COLUMNVALUE,'"','""')) ||'"');
L_SEPARATOR := ',';
END LOOP;
UTL_FILE.NEW_LINE( L_OUTPUT );
END LOOP;

--CLOSE CURSOR
DBMS_SQL.CLOSE_CURSOR(L_THECURSOR);

--CLOSE FILE
UTL_FILE.FCLOSE( L_OUTPUT );
EXCEPTION
WHEN OTHERS THEN
RAISE;
end outtocsv;

上述存储过程 SQL_TO_CSV 需要了解oracle中的utl_fiel、directory 的知识

下面调用 SQL_TO_CSV 存储过程的 前提就是定义一个directory,

定义语句如下: create or replace directory MYDIR as'c:\';

一个表的查询结果导出

下面就开始调用 存储过程 SQL_TO_CSV,将 select * from cus_event 的查询结果,导出为example.csv并放在MYDIR所代表的C:\下

declare

fhandleutl_file.file_type;

begin

sql_to_csv('select *from cus_event ','MYDIR','example.csv');

end;

【评论】上面是导出一个表,查询语句可以直接写,那么如果导出是多个表呢,那又该如果操作呢。既然是多个表,显然我们就要拼接sql语句,是sql语句动态变化,且导出的文件名也要动态变化。有两种方案,一将表名放在数组中,逐个调用;二是将表名放在文件中,逐个读取

方案一:用数组存放表名

从数组中取出表名,拼接sql语句,构造导出的csv文件名

declare

v_tablename varchar2(100); -----用来存表名

v_sql varchar2(1000); -----用来存组合起来查询的sql语句

type my_email is varray(200) of varchar2(40);--定义数组

tables_arr my_email;--定义一个数组变量

v_filename varchar2(100); ---用来存放构造的文件名

begin

tables_arr:=my_email('cus_grp_info','cus_event');--
给数组变量赋值

for i in 1..2 loop

dbms_output.put_line(tables_arr(i));

v_tablename:=tables_arr(i);

v_sql:='select * from '||v_tablename; -----构造查询的sql语句

dbms_output.put_line(v_sql);

v_filename:=v_tablename||'.csv'; -----构造查询导出后的文件名

dbms_output.put_line(v_filename);

sql_to_csv(v_sql,'MYDIR',v_filename); ----调用存储过程,将查询结果导出这里是核心部分

end loop;

end;

【评论】上述方案简单,但必须将表名手动放入数组中,例子中只到处两个表cus_grp_info,cus_event,但如果我们这里有上百张表,显然这种方法不太方便。我们通过会将表名存放在文件中。执行时从文件中读取表名,这样再多的表我们也能操作,且表的内容还可以随时方便的改变

方案二:用文件存表名

从文件中取出表名,拼接sql语句,构造导出的csv文件名

declare

v_tablenamevarchar2(100); -----用来存表名

v_sql varchar2(1000); -----用来存组合起来查询的sql语句

v_filenamevarchar2(100); ---用来存放构造的文件名

fhandleutl_file.file_type; -- 文件句柄

begin

fhandle:=utl_file.fopen('MYDIR','tablelist.txt','r');--获得tablelist的文件句柄

---这里tablelist.txt
就存放中将要查询的表的表名,txt文件放在MYDIR代表的c:\ 目录下

loop

begin

utl_file.get_line(fhandle,v_tablename);---从文件中一条一条读取表名,并存放在v_tablename

dbms_output.put_line(v_tablename);

v_sql:='select * from'||v_tablename; ---拼接查询语句

dbms_output.put_line(v_sql);

v_filename:=v_tablename||'.csv';---构造导出的csv文件名

dbms_output.put_line(v_filename);

exception

when no_data_foundthen ----直到文件末尾,即找不到数据了再停止

exit;

end ;

sql_to_csv(v_sql,'MYDIR',v_filename);----调用存储过程,将查询结果导出。这里核心部分

end loop;

end;

 

 

抱歉!评论已关闭.